How to return many Promises and wait for them all before doing other stuff

后端 未结 5 1800
北荒
北荒 2020-11-21 23:02

I have a loop which calls a method that does stuff asynchronously. This loop can call the method many times. After this loop, I have another loop that needs to be executed o

5条回答
  •  自闭症患者
    2020-11-21 23:15

    You can use Promise.all (spec, MDN) for that: It accepts a bunch of individual promises and gives you back a single promise that is resolved when all of the ones you gave it are resolved, or rejected when any of them is rejected.

    So if you make doSomeAsyncStuff return a promise, then:

        const promises = [];
    //  ^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−− use `const` or `let`, not `var`
        
        for (let i = 0; i < 5; i++) {
    //       ^^^−−−−−−−−−−−−−−−−−−−−−−−− added missing declaration
            promises.push(doSomeAsyncStuff());
        }
        
        Promise.all(promises)
            .then(() => {
                for (let i = 0; i < 5; i++) {
    //               ^^^−−−−−−−−−−−−−−−− added missing declaration
                    doSomeStuffOnlyWhenTheAsyncStuffIsFinish();    
                }
            })
            .catch((e) => {
                // handle errors here
            });
    

    MDN has an article on promises here. I also cover promsies in detail in Chapter 8 of my book JavaScript: The New Toys, links in my profile if you're interested.

    Here's an example:

     function doSomethingAsync(value) {
         return new Promise((resolve) => {
             setTimeout(() => {
                 console.log("Resolving " + value);
                 resolve(value);
             }, Math.floor(Math.random() * 1000));
         });
       }
       
       function test() {
           const promises = [];
           
           for (let i = 0; i < 5; ++i) {
               promises.push(doSomethingAsync(i));
           }
           
           Promise.all(promises)
               .then((results) => {
                   console.log("All done", results);
               })
               .catch((e) => {
                   // Handle errors here
               });
       }
       
       test();

    Sample output (because of the Math.random, what finishes first may vary):

    Resolving 3
    Resolving 2
    Resolving 1
    Resolving 4
    Resolving 0
    All done [0,1,2,3,4]
    

提交回复
热议问题