我對JavaScript(Node.js)和Promises相當陌生。我目前正在使用AWS Lambda和DynamoDB。在Bluebird中處理多個嵌套的異步操作(promise)
我有我從異步數據庫中獲取項目列表(已promisified AWS的SDK與藍鳥的承諾API)
對於這些項目,我需要可能檢索多個子項(也異步),然後對於每個子項,我必須執行另一個異步操作並確定此異步操作是否成功。
畢竟異步操作一個項目完成(即所有異步操作的子項成功或失敗),我需要更新的項目在DB的狀態(失敗/成功)。
這(下)是我到目前爲止。你能告訴我,如果我做得對嗎?它有沒有邏輯錯誤?可以改進嗎?
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"
}]
}]
}
一個解決方案(可能是一種醜陋的),這使我心裏是有一個全局對象外,然後在其內存儲結果。有沒有其他優雅的方式來做到這一點?
謝謝。