我的代码与此类似:
// Get the data via an AJAX call
fetchAjaxData()
.then(function(data) {
// Update or insert the data - cannot use a merge
data.forEach(function(item) {
updateTable(item)
.then(function(result)) {
// If no rows were updated, insert the item
if (result.rowsAffected == 0) {
insertIntoTable(item);
.then(function(result)) {
console.log("item added");
});
}
});
});
return data.length;
}).then(function(l) {
useInsertedItems(l);
});
问题是当useInsertedItems
运行时,数据可能尚未插入或更新。在此之前,如何确保数据完全更新或插入?
答案 0 :(得分:2)
有一篇很好的文章涵盖了你的案例。与此同时,你可以学到很多新东西! http://taoofcode.net/promise-anti-patterns/
function workMyCollection(arr) {
return arr.reduce(function(promise, item) {
return promise.then(function(result) {
return doSomethingAsyncWithResult(item, result);
});
}, q());
}
答案 1 :(得分:2)
通过返回值承诺信号完成,因此您应该返回updateItem
和insertIntoTable
链。聚合承诺是通过Promise.all
(或$ q.all,Q.all,$ .when等来完成的,具体取决于库):
更正后的代码会执行以下两项操作:
fetchAjaxData()
.then(function(data) {
// Update or insert the data - cannot use a merge
// map is like `each` with return values for each item
var ps = data.map(function(item) {
return updateTable(item)
.then(function(result)) {
// If no rows were updated, insert the item
if (result.rowsAffected == 0) {
return insertIntoTable(item); // note the return
.then(function(result)) {
console.log("item added");
});
}
});
});
return Promise.all(ps).then(function(){ return data.length; });
}).then(function(l) {
useInsertedItems(l);
});