2017-08-31 32 views
0

我正在研究一个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将不符合条件的条件更新作为例外处理)。

你会如何解决这个问题?

+0

感谢您接受的答案,但它是我的编辑之前。希望你更喜欢第二种方法,我认为它更好。 – Evert

回答

1

编写自己的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; 
    } 
    } 
]); 
+0

我还没有测试,但你的第二个答案似乎更好,谢谢! – justkevin