一尘不染

使angular.forEach等待下一个对象后的承诺

angularjs

我有一个对象列表。对象将传递给延迟函数。我只想在上一次调用解决后才使用下一个对象调用函数。有什么办法可以做到吗?

angular.forEach(objects, function (object) {
    // wait for this to resolve and after that move to next object
    doSomething(object);
});

阅读 240

收藏
2020-07-04

共1个答案

一尘不染

在ES2017之前和之后async/await(请参见下文中的ES2017中的选项),.forEach()如果要等待诺言就不能使用,因为诺言没有阻塞。Javascript和Promise不会那样工作。

  1. 您可以链接多个promise,并使promise基础结构对它们进行排序。

  2. 您可以手动进行迭代,并且仅在先前的承诺完成时才进行迭代。

  3. 您可以使用类似的库,asyncBluebird将为您排序的库。

有很多其他选择,但.forEach()不会为您做。


这是一个使用promise与角度promise的链进行排序的示例(假设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功能确实使用非功能基于循环比如当让你“等待”诺言继续循环迭代之前履行forwhile

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

2020-07-04