NodeJS [SOLVED]: Wait promise inside for loop

NodeJS [SOLVED]: Wait promise inside for loop

Home Forums Scripting NodeJS Tutorials NodeJS [SOLVED]: Wait promise inside for loop

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #245843

    Cloudy Point
    Keymaster

    QuestionQuestion

    let currentProduct;
    
    for (let i = 0; i < products.length; i++) { 
        currentProduct = products[i];
    
        subscription.getAll(products[i]._id)
            .then((subs) => {
                update(subs, currentProduct);
            });
    }
    

    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…

    #245844

    Cloudy Point
    Keymaster

    Accepted AnswerAnswer

    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);
        */
    }
    

    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))
    }
    

    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).

    Source: https://stackoverflow.com/questions/48014050/wait-promise-inside-for-loop
    Author: CRice
    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.