如何在预期错误时处理Node.js中的多个并行回调/承诺?
我正在研究一个Node.js函数,它将对Amazon DynamoDB进行三次并发调用:put(存储一些信息),query(获取一些信息)和update(有条件地更新一些信息)。通话不依赖于对方。如何在预期错误时处理Node.js中的多个并行回调/承诺?
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.put(params1, callback);
docClient.query(params2, callback);
docClient.update(params3, callback);
或承诺:
Amazon的SDK可以异步使用任何回调调用它们
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);
}
});
});
});
}
上述功能基本要求then
的每一个承诺,存储所有的结果,一旦它拥有所有的结果,它将返回顶部承诺。这与Promise.all();
的实现非常相似。
但是,我不完全确定这是如何实现它。首先,错误全部转换为null
,并且或多或少会“丢失”。我认为这不是一个好的设计,因为只需要捕捉您期望的特定异常就是一个好主意。例如,假设您的客户端抛出PreconditionFailed
异常,并且您只关心更新调用。只要抓住这一点就太容易了。
例子:
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;
}
}
]);
我还没有测试,但你的第二个答案似乎更好,谢谢! – justkevin
感谢您接受的答案,但它是我的编辑之前。希望你更喜欢第二种方法,我认为它更好。 – Evert