当预期会出现错误时,如何在Node.js中处理多个并行回调/承诺?

当预期会出现错误时,如何在Node.js中处理多个并行回调/承诺?,node.js,amazon-web-services,promise,Node.js,Amazon Web Services,Promise,我正在开发一个Node.js函数,它将对AmazonDynamodB进行三个并发调用:put(存储一些信息)、query(获取一些信息)和update(有条件地更新一些信息)。这些呼叫并不相互依赖 Amazon的SDK可以使用以下任一回调异步调用它们: var docClient = new AWS.DynamoDB.DocumentClient(); docClient.put(params1, callback); docClient.query(params2, callback); do

我正在开发一个Node.js函数,它将对AmazonDynamodB进行三个并发调用:put(存储一些信息)、query(获取一些信息)和update(有条件地更新一些信息)。这些呼叫并不相互依赖

Amazon的SDK可以使用以下任一回调异步调用它们:

var docClient = new AWS.DynamoDB.DocumentClient();
docClient.put(params1, callback);
docClient.query(params2, callback);
docClient.update(params3, callback);
或承诺:

var promise1 = docClient.put(params1).promise();
var promise2 = docClient.query(params2).promise();
var promise3 = docClient.update(params3).promise();
我想处理查询调用的结果,但只能在其他两个调用完成后处理。我不在乎它们发生的顺序,也不在乎它们是否成功

Promise.all()可以做到这一点,除了更新可能会抛出异常(Amazon将不符合条件的条件更新视为异常)这一事实


如何解决这个问题?

编写自己的
Promise.all()
变体并不难,它会返回每个结果,如果其中任何一个失败,可能会返回
null
。例如:

// Sorry, completely blanking on a better function name.
function myAll(promises) {

  return new Promise((res, rej) => {
    var settled = 0;
    var results = [];
    promises.forEach(function(promise, index) {
      promise.then( result => {
        results[index] = result;
      }).catch( err => {
        results[index] = null
      }).then( () => {
         settled++;
         if (promises.length === settles) {
            res(results);
         }
      });
    });

  });
}
上面的函数基本上会调用
,然后对每个承诺调用
,存储所有结果,一旦得到所有结果,它将返回最重要的承诺。这非常类似于
Promise.all()已实现

然而,我不完全确定我是否会这样实现它。首先,错误都被转换为
null
,或多或少地“丢失”。我认为这不是一个好的设计,因为捕捉您期望的特定异常是一个好主意。例如,让我们假设您的客户端抛出一个
异常,而您只关心更新调用的异常。很容易就能抓住它

例如:

Promise.all([
  docClient.put(params1).promise(),
  docClient.query(params2).promise(),
  async () => {
    try {
      return docClient.update(params3).promise()
    } catch (e) {
      if (!(e instanceof PreconditionFailedException)) {
        // rethrow
        throw e;
      }
      return null;
    }
  }
]);

谢谢你接受我的答案,但那是在我编辑之前。希望你更喜欢第二种方法,我认为它更好。我还没有测试,但你的第二种答案似乎更好,谢谢!