简体   繁体   English

然后/捕获如何处理一组Promises

[英]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: 您的updateArticleUiupdateArticleUiWithErrors应该具有各自的返回值,以便在查看结果数组时可以区分是否有错误:

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已经被解决了,或者是thencatch

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM