顺序承诺抛出承诺拒绝警告

时间:2019-09-21 17:51:17

标签: javascript node.js es6-promise

情况

我正在尝试建立一种顺序执行诺言的方式。我已经在线上学习了其中一部教程,并提出了以下建议:

function get_data(value){
  value = 1
  var sheet = SpreadsheetApp.getActiveSheet()
  var range = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn())
  var filter = range.getFilter() || range.createFilter();
  var foo_index = 1; // column A
  var filterValue = SpreadsheetApp.newFilterCriteria().whenTextEqualTo(value).build()

  filter.setColumnFilterCriteria(foo_index, filterValue)

  // new code
  var data = []

  for (var i = 1; i < sheet.getLastRow(); i++) {
    if(!sheet.isRowHiddenByFilter(i)) {
      var row_data = sheet.getRange(i, 1, 1, sheet.getLastColumn()).getValues()
      data.push(row_data[0])
    }
  }
  // end new code

  Logger.log(data)

  return data
}

主文件

https://pastebin.com/GLdrKWHp

我要保证依次解决并处理错误?

https://pastebin.com/Ktw6zz9u

出什么问题了?

  

但是,有时我会在终端控制台中偶尔收到以下警告:

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

我们如何防止这种情况发生?

其他信息

如果您需要任何其他信息或需要邀请参加该项目,请随时询问我。我知道可能需要更多信息来进一步调试该问题。

更新

当我更改如下所示的诺言之一时,它不会显示错误。

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

1 个答案:

答案 0 :(得分:1)

问题是您已经立即开始所有动作,并将它们产生的承诺放入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 -一个返回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,它很容易使用。