Как обработать массив Promises then / catch - PullRequest
0 голосов
/ 10 сентября 2018

Я не знаю, как разрешить эту ситуацию, используя обещания JS.

Представьте, что у меня есть несколько статей, и я хочу отправить запрос на исправление для их обновления. Я отправляю один запрос на статью. Если запрос одной статьи успешно выполняется, я обновляю эту статью, но если запрос не выполняется, я обновляю статью по-другому. Также я хочу показать пользователю сообщение, информирующее, правильно ли обновлены все статьи.

Это не мой реальный сценарий, и это может быть странным примером. Но это то, чего я хочу достичь в своем приложении React.

Вот что я пытаюсь сделать прямо сейчас:

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());
};

Это не работает, потому что Promise.all всегда выполняет обратный вызов then, все обещания выполняются или нет.

Спасибо!

Ответы [ 4 ]

0 голосов
/ 10 сентября 2018

Это работает:

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"]);
0 голосов
/ 10 сентября 2018

Проблема в том, что вы ловите ошибку, выданную

const promise = axios
      .patch('/articles', article)
      .then(() => updateArticleUi(article))
      .catch(() => updateArticleUiWithError(article));

, вы должны либо выдать новую ошибку в аксиосах catch(), либо позволить ошибке всплыть, удалив catch изAxios Call.

0 голосов
/ 10 сентября 2018

Ваши 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();
    }
  });
}
0 голосов
/ 10 сентября 2018

Promise.all будет звонить всегда, потому что обещание, которое вы добавляете к promises, уже разрешено с then или catch, прикрепленным выше

если вы хотите, чтобы catch происходило в цепочке .all, просто добавьте исключение в updateArticleUiWithErro функцию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...