在 for 循环中等待 promise [英] Wait promise inside for loop

查看:36
本文介绍了在 for 循环中等待 promise的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

let currentProduct;

for (let i = 0; i < products.length; i++) { 
    currentProduct = products[i];

    subscription.getAll(products[i]._id)
        .then((subs) => {
            update(subs, currentProduct);
        });
}

我正在使用 bluebird,方法 getAllupdate 返回承诺.我怎么能说等到两个承诺返回,然后更新 currentProduct 值"?我对 JS 很陌生...

I'm using bluebird, the methods getAll and update return promises. How can I say "Wait until the two promises return, then update the currentProduct value"? I'm quite new to JS...

推荐答案

如果您可以使用 async/await,这将很简单:

This will be straightforward if you can use async/await:

// Make sure that this code is inside a function declared using
// the `async` keyword.
let currentProduct;

for (let i = 0; i < products.length; i++) { 
    currentProduct = products[i];

    // By using await, the code will halt here until
    // the promise resolves, then it will go to the
    // next iteration...
    await subscription.getAll(products[i]._id)
        .then((subs) => {
            // Make sure to return your promise here...
            return update(subs, currentProduct);
        });

    // You could also avoid the .then by using two awaits:
    /*
    const subs = await subscription.getAll(products[i]._id);
    await update(subs, currentProduct);
    */
}

或者如果你只能使用普通的promise,你可以遍历你所有的产品,并将每个promise放在最后一个循环的.then中.这样,它只会在前一个已经解决后才前进到下一个(即使它会先迭代整个循环):

Or if you can only use plain promises, you can loop through all your products, and put each promise in the .then of the last loop. In that way, it will only advance to the next when the previous has resolved (even though it will have iterated the whole loop first):

let currentProduct;

let promiseChain = Promise.resolve();
for (let i = 0; i < products.length; i++) { 
    currentProduct = products[i];

    // Note that there is a scoping issue here, since
    // none of the .then code runs till the loop completes,
    // you need to pass the current value of `currentProduct`
    // into the chain manually, to avoid having its value
    // changed before the .then code accesses it.

    const makeNextPromise = (currentProduct) => () => {
        // Make sure to return your promise here.
        return subscription.getAll(products[i]._id)
            .then((subs) => {
                // Make sure to return your promise here.
                return update(subs, currentProduct);
            });
    }

    // Note that we pass the value of `currentProduct` into the
    // function to avoid it changing as the loop iterates.
    promiseChain = promiseChain.then(makeNextPromise(currentProduct))
}

在第二个片段中,循环只是设置了整个链,但不会立即执行 .then 中的代码.您的 getAll 函数不会运行,直到每个前一个函数依次解决(这是您想要的).

In the second snippet, the loop just sets up the entire chain, but doesn't execute the code inside the .then immediately. Your getAll functions won't run until each prior one has resolved in turn (which is what you want).

这篇关于在 for 循环中等待 promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆