我有一个对象列表。对象将传递给延迟函数。我只想在上一次调用解决后才使用下一个对象调用函数。有什么办法可以做到吗?
angular.forEach(objects, function (object) { // wait for this to resolve and after that move to next object doSomething(object); });
在ES2017之前和之后async/await(请参见下文中的ES2017中的选项),.forEach()如果要等待诺言就不能使用,因为诺言没有阻塞。Javascript和Promise不会那样工作。
async/await
.forEach()
您可以链接多个promise,并使promise基础结构对它们进行排序。
您可以手动进行迭代,并且仅在先前的承诺完成时才进行迭代。
您可以使用类似的库,async或Bluebird将为您排序的库。
async
Bluebird
有很多其他选择,但.forEach()不会为您做。
这是一个使用promise与角度promise的链进行排序的示例(假设objects是一个数组):
objects
objects.reduce(function(p, val) { return p.then(function() { return doSomething(val); }); }, $q.when(true)).then(function(finalResult) { // done here }, function(err) { // error here });
而且,使用标准的ES6许诺,将是:
objects.reduce(function(p, val) { return p.then(function() { return doSomething(val); }); }, Promise.resolve()).then(function(finalResult) { // done here }, function(err) { // error here });
这是一个手动排序的示例(假设objects是一个数组),尽管它不像上面的选项那样报告回完成或错误:
function run(objects) { var cntr = 0; function next() { if (cntr < objects.length) { doSomething(objects[cntr++]).then(next); } } next(); }
ES2017
在ES2017,该async/wait功能确实使用非功能基于循环比如当让你“等待”诺言继续循环迭代之前履行for或while:
async/wait
for
while
async function someFunc() { for (object of objects) { // wait for this to resolve and after that move to next object let result = await doSomething(object); } }
该代码必须包含在一个async函数中,然后您可以await用来告诉解释器在继续循环之前等待承诺解决。注意,虽然这似乎是“阻止”类型的行为,但它并不阻止事件循环。事件循环中的其他事件仍可以在期间进行处理await。
await