[英]How to handle an array of Promises then/catch
I don't know to to resolve this situation using JS promises. 我不知道使用JS promise解决这种情况。
Imagine I have some articles and I want to send a patch request to update them. 想象一下,我有一些文章,并且想发送补丁请求来更新它们。 I send one request per article.
每篇文章我发送一个请求。 If the request of one article success then I update that article, but if the request fails, then I update the article differently.
如果一篇文章的请求成功,那么我将更新该文章,但是如果请求失败,那么我将以另一种方式更新该文章。 Also I want to show a message to the user informing if all the articles have been updated correctly or not.
另外,我想向用户显示一条消息,告知所有文章是否已正确更新。
This is not my real scenario and this may be a weird example. 这不是我的真实情况,这可能是一个奇怪的例子。 But it's what I want to accomplish in my React app.
但这是我想在我的React应用程序中完成的。
Here is what I'm trying to do right now: 这是我现在正在尝试做的事情:
const saveArticles = articles => {
const promises = [];
articles.forEach(article => {
const promise = axios
.patch('/articles', article)
.then(() => updateArticleUi(article))
.catch(() => updateArticleUiWithError(article));
promises.push(promise);
});
Promise.all(promises)
.then(() => tellTheUserThereWasNoErrors())
.catch(() => tellTheUserThereWasSomeErrors());
};
This isn't working because the Promise.all
is always executing the then
callback, weather all promises succeed or not. 这是行不通的,因为
Promise.all
始终执行then
回调,无论所有诺言成功与否。
Thanks! 谢谢!
Your updateArticleUi
and updateArticleUiWithErrors
should have the respective return values so that you can distinguish whether there was an error or not when looking at the array of results: 您的
updateArticleUi
和updateArticleUiWithErrors
应该具有各自的返回值,以便在查看结果数组时可以区分是否有错误:
function updateArticleUi(article) {
…
return {success: true};
}
function updateArticleUiWithError(article, error) {
…
return {success: false};
}
function saveArticles(articles) {
const promises = articles.map(article => {
return axios.patch('/articles', article).then(() =>
updateArticleUi(article)
, err =>
updateArticleUiWithError(article, err)
);
});
return Promise.all(promises).then(results =>
if (results.every(res => res.success)) {
tellTheUserThereWasNoErrors();
} else {
tellTheUserThereWasSomeErrors();
}
});
}
This works: 这有效:
function axiosPatchRequest(url,data) { return new Promise(function (resolve, reject) { if (data) { resolve(url); } else { reject('DATA_NOT_FOUND'); } }) } function updateArticleUi(data,article) { return new Promise(function (resolve, reject) { resolve({type:"updateArticleUi ",data,article}); }) } function updateArticleUiWithError(data,article) { return new Promise(function (resolve, reject) { reject({type:"updateArticleUiWithError ",data,article}); }) } function tellTheUserThereWasNoErrors(data){ console.log("tellTheUserThereWasNoErrors",data); } function tellTheUserThereWasSomeErrors(error){ console.log("tellTheUserThereWasSomeErrors",error); } const execute = (articles)=>{ const promises = []; articles.forEach(article => { const promise = axiosPatchRequest('/articles', article) .then((data) => { return updateArticleUi(data,article); }) .catch((error) => { return updateArticleUiWithError(error,article); }); promises.push(promise); }); Promise.all(promises) .then((data) => tellTheUserThereWasNoErrors(data)) .catch((error) => tellTheUserThereWasSomeErrors(error)); }; execute(["one","","three"]); execute(["one","two","three"]);
Promise.all
will always call then because the promise you add to promises
is already resolved one with either then
or catch
attached above Promise.all
会一直调用,因为您添加到promises
已经被解决了,或者是then
或catch
if you want to see catch
to happen in .all
chain just throw some exeption in updateArticleUiWithErro
function 如果您想看到
catch
发生在.all
链中,只需在updateArticleUiWithErro
函数中抛出一些updateArticleUiWithErro
The problem is that you are catching the error thrown by 问题是您正在捕获由抛出的错误
const promise = axios
.patch('/articles', article)
.then(() => updateArticleUi(article))
.catch(() => updateArticleUiWithError(article));
you should either throw a new error in the axios catch()
or let the error bubble up by removing the catch
from the axios call. 您应该在axios
catch()
抛出一个新错误,或者通过从axios调用中删除catch
来让错误冒泡。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.