我需要在Nodejs中执行一些异步任务。在这种情况下,我需要迭代抛出JSON的al级别。出于这个原因,我需要按顺序“迭代”同步该对象。
我正在使用此代码进行测试,这是一个改编自this site
的简单示例var fnlist = [ doFirstThing, doSecondThing, doThirdThing, lastThing];
// Promise returning functions to execute
function doFirstThing(){ return Promise.resolve(1); }
function doSecondThing(res){ return Promise.resolve(res + 1); }
function doThirdThing(res){ return Promise.resolve(res + 2); }
function lastThing(res){ console.log("result:", res); }
// Execute a list of Promise return functions in series
function pseries(req,json,list) {
var p = Promise.resolve();
return doFirstThing()
.then((value) => {
console.log('value');
console.log(value);
return doSecondThing(value).then((value2) => {
console.log('value2');
console.log(value2);
});
});
}
router.get('/', function(req, res, next) {
var thisArray = json[0].array;
for(var i = 0;i < thisArray.length; i++){
pseries(req,json,fnlist);
}
});
控制台输出为:
1
value
1
value
1
value2
2
value2
2
value2
2
并且仍然有效,因为我需要这种流程:
value
1
value2
2
value
1
value2
2
value
1
value2
2
我知道我需要使用 promises工厂,以便在创建它们后不立即执行它们,但现在似乎无法正常工作。我知道我不能使用.all 因为我需要使用下一个承诺中的一些数据。
有什么想法吗?谢谢!
答案 0 :(得分:2)
您已在for
循环中启动了多个独立的承诺链(每次调用pseries()
都是一个单独的承诺链)。因此,您无法控制单独的承诺链的排序。如果你想控制一个链与另一个链,那么你将不得不链接它们(例如将它们链接在一起),所以排序是明确的而不是偶然的。
您看到的输出并不令人惊讶,因为您的for
循环所做的第一件事就是注册一堆.then()
个处理程序。因为已经为这些承诺解决了承诺,所以.then()
循环完成后,for
处理程序都排队等待运行(.then()
处理程序始终排队异步运行) 即可。 for
循环完成,然后第一批.then()
个处理程序全部运行。运行它们的过程会安排另外三个.then()
个处理程序。然后排队等待它们在第一批.then()
处理程序完成时运行。虽然我解释了为什么你得到你看到的订单的可能逻辑,但这不能保证。这些都是异步操作,你唯一知道的是他们将来会完成一些不确定的时间。如果你想要明确的订单,你必须通过显式同步你的承诺来强迫它。
您可以使用array.reduce()
相当常见的设计模式,按照已知顺序对数组进行迭代排序:
router.get('/', function(req, res, next) {
var thisArray = json[0].array;
thisArray.reduce(function(p, item) {
return p.then(function() {
return pseries(req,json,fnlist);
});
}, Promise.resolve()).then(function(result) {
// all done here
}, function(err) {
// error here
});
});
答案 1 :(得分:0)
尝试使用foreach链接所有承诺:
var sequence = Promise.resolve();
// Loop through our chapter urls
story.chapterUrls.forEach(function(chapterUrl) {
// Add these actions to the end of the sequence
sequence = sequence.then(function() {
return getJSON(chapterUrl);
}).then(function(chapter) {
addHtmlToPage(chapter.html);
});
});
对于更复杂的组合,请查看此页面: http://www.html5rocks.com/en/tutorials/es6/promises/#toc-parallelism-sequencing