我目前正在努力掌握以下实施的结构:
// Method from API Class (layer for communicating with the API)
call() {
// Return axios request BUT handle specific API errors e.g. '401 Unauthorized'
// and prevent subsequent calls to `then` and `catch`
}
// Method from Form Class (used for all forms)
submit() {
// Call the `call` method on the API class and process
// the response.
// IF any validation errors are returned then
// process these and prevent subsequent calls to `then`
// and `catch`
}
// Method on the component itself (unique for each form)
onSubmit() {
// Call the `submit` method on the Form class
// Process the response
// Handle any errors that are not handled by the parent
// methods
}
我已经像这样实现了这个:
// Method from API Class (layer for communicating with the API)
call() {
// The purpose of this is to execute the API request and return
// the promise to the caller. However, we need to catch specific
// API errors such as '401 Unauthorized' and prevent any subsequent
// `then` and `catch` calls from the caller
return new Promise((resolve, reject) => {
this.axios.request(request)
.then(response => {
resolve(response); // Do I actually need to do this?
})
.catch(error => {
// Here we need to handle unauthorized errors and prevent any more execution...
reject(error);
});
});
}
// Method from Form Class (used for all forms)
submit() {
// The purpose of this is to call the API, and then, if it
// returns data, or validation errors, process these.
return new Promise((resolve, reject) => {
api.call()
.then(response => {
// Process form on success
this.onSuccess(response.data);
resolve(response.data);
})
.catch(error => {
// Process any validation errors AND prevent
// any further calls to `then` and `catch` from
// the caller (the form component)
this.onFail(error.response.data.error.meta);
reject(error);
})
.then(() => this.processing = false); // This MUST run
});
}
// Method on the component itself (unique for each form)
onSubmit() {
this.form.submit()
.then(response => {
// This should only run if no errors were caught in
// either of the parent calls
// Then, do some cool stuff...
});
}
我的评论应该解释我想要实现的目标,但要明确:
then
和catch
的任何进一步调用从调用类/组件运行?new Promise
?axios.request
已经返回Promise
但我不知道如何访问resolve
和reject
方法,而不用新的Promise
{1}}。如果这是错误的,请随时纠正... 答案 0 :(得分:4)
首先:当已经承诺合作时,不需要new Promise
。所以作为第一步,让我们修复(比如说)call
:
call() {
return this.axios.request(request)
.then(response => {
// ...
})
.catch(error => {
// ...
});
}
如何捕获某些错误,然后阻止对
then
和catch
的任何进一步调用从调用类/组件运行?
你没有。如果您要退回承诺,则必须解决(解决或拒绝)。要么涉及后续处理程序运行。承诺正是如此:承诺您要么提供值(分辨率)要么提供错误(拒绝)。
您可能遗漏的关键概念(很多人都这么做!)是then
和catch
返回新承诺,根据他们的承诺解决/拒绝承诺处理程序。
您可以使用catch
处理程序:
...但你无法抑制对后续回调的调用。
您可以使用then
处理程序:
因此,例如,如果您有错误条件可以纠正(这种情况相对较少,但发生了),您可以这样做
.catch(error => {
if (/*...the error can be corrected...*/) {
return valueFromCorrectingTheProblem;
}
throw error; // Couldn't correct it
})
如果返回值(或解析的promise),catch
返回的承诺将使用该值解析。如果您抛出(或返回拒绝的承诺),catch
返回的承诺将拒绝。
每次返回时,是否真的有必要创建一个新的Promise?
不,见上文。 (还有好问题。)
我知道
axios.request
已经返回了一个Promise,但我不知道如何在不使用新Promise包装它的情况下访问resolve
和reject
方法。
你没有;您使用then
和catch
。他们返回新的承诺,根据处理程序中发生的情况解决/拒绝承诺。