顺序承诺抛出 PromiseRejectionWarnings

Sequential Promise Throws PromiseRejectionWarnings

情况

我正在尝试设置一种按顺序执行承诺的方式。我遵循了其中一个在线教程并想出了这个:

  return promises.reduce((promiseChain, currentTask) => {
    return promiseChain.then(chainResults => {
        return currentTask.then(currentResult => {
             return [ ...chainResults, currentResult ];
        }).catch(error => {
          errors.push(error);
          return;
        });
    });
  }, Promise.resolve([])).then(arrayOfResults => {
      console.log("ARRAY_OF_RESULTS", arrayOfResults);
      return errors.length > 0 ? response.status(400).send(errors) : response.status(200).send("De advertenties zijn succesvol verstuurd naar alle partner portalen");
  });
});

主文件

https://pastebin.com/GLdrKWHp

我想顺序解析和处理哪些 promise 的错误?

https://pastebin.com/Ktw6zz9u

有什么问题?

However, somehow, once in a while I get the following warning in my terminal console:

(node:10894) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 62)
(node:10894) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 62)
ARRAY_OF_RESULTS undefined
(node:10894) UnhandledPromiseRejectionWarning: #<Object>
(node:10894) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 71)
(node:10894) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 71) 

How can we prevent this from happening?

附加信息

如果您需要任何其他信息或需要项目邀请,请随时联系我。我知道可能需要额外的信息来进一步调试这个问题。

更新

当我更改 return 调用时,我的一个承诺的 catch 如下所示,它不会显示错误。

```//return { status: error.response.status, partner: "autoscout", message: error.response.statusText };
return Promise.reject({ status: error.response.status, partner: "autoscout", message: error.response.statusText })```

问题是您已经同时启动了所有操作,并将它们产生的承诺放入 promises 数组中。这里没有任何内容是 运行 顺序。你应该只写

Promise.allSettled(promises).then(arrayOfResults => {
  console.log("ARRAY_OF_RESULTS", arrayOfResults);
  const errors = arrayOfResults.filter(res => res.status == "rejected").map(res => res.reason);
  if (errors.length > 0)
    response.status(400).send(errors);
  else
    response.status(200).send("De advertenties zijn succesvol verstuurd naar alle partner portalen");
});

如果您真的想按顺序执行您的操作,则需要在 reduce 回调中启动每个单独的操作。目前,使用 currentTask.then(…) 你只是按顺序挂钩到解决事件,但是这些动作很久以前就开始了 - 当一个承诺被拒绝时你可能还没有挂钩它,导致未处理的拒绝。因此,您需要在该数组中放置一个 task - 一个 returns promise 的函数:

const tasks = []; // an array of functions to be run sequentially
if(autoscoutEnabled) {
  tasks.push(() => createAutoscoutAd("/vehicles", jsonAutoscout, "tokenteststring"));
  tasks.push(() => addImageToAutoscoutAd("/vehicles/7e59591f-c5a3-974e-e452-2951040ae4ee", file, type, "tokenteststring"));
}

if (marktplaatsEnabled) {
  tasks.push(() => createMarktplaatsAd("/advertisements", jsonMarktplaats, "tokenteststring"));
  tasks.push(() => addImageToMarktplaatsAd("/advertisements/m1427566569", file, type, "tokenteststring"));
}

return tasks.reduce((promiseChain, currentTask) => {
  return promiseChain.then(errors => {
    const currentPromise = currentTask();
// this is the important line         ^^
    return currentPromise.then(() => errors, error => {
      errors.push(error);
      return errors;
    });
  });
}, Promise.resolve([])).then(errors => {
  console.log("ARRAY_OF_RESULTS", arrayOfResults);
  if (errors.length > 0)
    response.status(400).send(errors);
  else
    response.status(200).send("De advertenties zijn succesvol verstuurd naar alle partner portalen");
});

但是,对于顺序执行,我建议使用 async/await,这很容易使用。