本文介绍了在转到下一个对象后使 angular.forEach 等待承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对象列表.对象被传递给延迟函数.我想仅在解决上一个调用后使用下一个对象调用该函数.有什么办法可以做到这一点吗?

I have a list of objects. The objects are passed to a deferred function. I want to call the function with the next object only after the previous call is resolved. Is there any way I can do this?

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 就不能那样工作.

Before ES2017 and async/await (see below for an option in ES2017), you can't use .forEach() if you want to wait for a promise because promises are not blocking. Javascript and promises just don't work that way.

  1. 您可以链接多个承诺,并使承诺基础设施对它们进行排序.

  1. You can chain multiple promises and make the promise infrastructure sequence them.

您可以手动迭代并仅在前一个 Promise 完成时推进迭代.

You can iterate manually and advance the iteration only when the previous promise finishes.

您可以使用像 asyncBluebird 这样的库来为您排序.

You can use a library like async or Bluebird that will sequence them for you.

有很多不同的选择,但 .forEach() 不会为你做.

There are lots of different alternatives, but .forEach() will not do it for you.

以下是使用 angular promise 链接 promise 的排序示例(假设 objects 是一个数组):

Here's an example of sequencing using chaining of promises with angular promises (assuming objects is an array):

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 承诺,这将是:

And, using standard ES6 promises, this would be:

objects.reduce(function(p, val) {
    return p.then(function() {
        return doSomething(val);
    });
}, Promise.resolve()).then(function(finalResult) {
    // done here
}, function(err) {
    // error here
});

这是手动排序的示例(假设 objects 是一个数组),尽管这不会像上述选项那样报告完成或错误:


Here's an example of manually sequencing (assuming objects is an array), though this does not report back completion or errors like the above option does:

function run(objects) {
    var cntr = 0;

    function next() {
        if (cntr < objects.length) {
            doSomething(objects[cntr++]).then(next);
        }
    }
    next();
}

ES2017

在 ES2017 中,async/wait 功能确实允许您在使用基于非函数的循环(例如 forwhile:

In ES2017, the async/wait feature does allow you to "wait" for a promise to fulfill before continuing the loop iteration when using non-function based loops such as for or 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 期间仍然可以处理事件循环中的其他事件.

The code has to be contained inside an async function and then you can use await to tell the interpreter to wait for the promise to resolve before continuing the loop. Note, while this appears to be "blocking" type behavior, it is not blocking the event loop. Other events in the event loop can still be processed during the await.

这篇关于在转到下一个对象后使 angular.forEach 等待承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 08:58