【发布时间】:2015-12-06 23:55:25
【问题描述】:
我对 JavaScript (Node.js) 和 Promises 还很陌生。我目前正在使用 AWS Lambda 和 DynamoDB。
我有一个从数据库中异步获取的项目列表(已使用 bluebird promise API 向 AWS SDK 承诺。)
对于这些项目中的每一个,我可能需要检索多个子项目(也是异步的),然后对于每个子项目,我必须执行另一个异步操作并确定此异步操作是否成功。
在为一个项目完成所有异步操作之后(即所有子项目的异步操作成功或失败),我需要更新数据库中项目的状态(失败/成功。)
这(下)是我目前所拥有的。你能告诉我我是否正确地做到了这一点?里面有没有逻辑错误?可以改进吗?
var doc = require('dynamodb-doc');
var promise = require("bluebird");
var dynamodb = new doc.DynamoDB();
var params = { /* ... */ };
promise.promisifyAll(Object.getPrototypeOf(dynamodb));
dynamodb.queryAsync(params)
.then(function(data) {
var items = data.Items;
var promises = items.map(function(item) {
params = { /* ...*/ };
return dynamodb.queryAsync(params)
.then(function(data2) {
var childItems = data2.Items;
var morePromises = childItems.map(function(device) {
return doAsyncWork()
.then(function success() {
console.log("Success!");
})
.catch(function error(err) {
console.log("Error!");
})
});
return promise.all(morePromises);
})
.then(function() {
// Update status for item in DB
params = { /* ...*/ };
return dynamodb.updateItemAsync(params);
});
});
return promise.all(promises);
})
.then(function() {
var response = { /* ... */ };
context.succeed(response);
})
.catch(function(err) {
context.fail(err);
});
其他一些事情:
对于要完成的项目的所有异步操作,我使用 Promise.all(),从文档中我可以看到,即使一个承诺被拒绝,后续的承诺也会被拒绝。我不希望这种情况发生,即使一个承诺被拒绝,我也希望它继续下去。
同样,我最后使用 Promise.all() 等待所有项目完成处理的所有项目。如果一个失败了,其余的就不会被处理,对吧?我该如何克服这个问题?
有很多嵌套,我该如何改进这段代码?
我需要有一种方法来整合所有结果并将其作为响应传递,例如像这样:
{
"Results": [{
"ItemId": " ... ",
"Status": "Success",
"ChildItems": [{
"ChildItemId": " ... ",
"Status": "Success"
/* ...
...
...
*/
}]
}, {
"ItemId": " ... ",
"Status": "Error",
"ChildItems": [{
"ChildItemId": " ... ",
"Status": "Success"
}, {
"ChildItemId": " ... ",
"Status": "Error"
}]
}]
}
我想到的一个解决方案(可能有点难看)是在外部有一个全局对象,然后将结果存储在其中。有没有其他优雅的方式来做到这一点?
谢谢。
【问题讨论】:
标签: javascript node.js asynchronous promise bluebird