且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何返回许多承诺并在执行其他操作之前等待所有这些承诺

更新时间:2023-10-30 21:37:40

您可以使用 Promise.all 规范 MDN ):它接受一堆单独的承诺,并给您带来一个单独的承诺,当您所有的承诺都得到解决时


因此,如果您使 doSomeAsyncStuff 返回一个诺言,则:

  const promises = []; 
// ^^^^^---------------使用`const`或`let`,而不是`var `

for(让i = 0; i< 5; i ++){
// ^^^ -------------------- ---增加了丢失的声明
promises.push(doSomeAsyncStuff());
}

Promise.all(承诺)
.then(()=> {
for(let i = 0; i< 5; i ++) {
// ^^^ -----添加了缺少的声明
doSomeStuffOnlyWhenTheAsyncStuffIsFinish();
}
})
.catch((e)=> {
//在这里处理错误
});

MDN上有关于诺言的文章此处。我还会在我的书 JavaScript:The New Toys 的第8章中详细介绍一些许诺,如果您有兴趣的话,可在我的个人资料中链接。


下面是一个示例:


 函数doSomethingAsync(value){
return new Promise((resolve)=&gt ; {
setTimeout(()=> {
console.log( Resolution + 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(应许)
.then((结果)=> {
console.log(全部完成,结果);
})
.catch((e)=> {
//在这里处理错误
});
}

test();


示例输出(由于 Math.random ,首先完成的内容可能会有所不同):

 
解决3
解决2
解决1
解决4
解决0
全部完成[0,1,2,3,4]


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 only when all the asynchronous stuff is done.

So this illustrates what I want:

for (i = 0; i < 5; i++) {
    doSomeAsyncStuff();    
}

for (i = 0; i < 5; i++) {
    doSomeStuffOnlyWhenTheAsyncStuffIsFinish();    
}

I'm not very familiar with promises, so could anyone help me to achieve this?

This is how my doSomeAsyncStuff() behaves:

function doSomeAsyncStuff() {
    var editor = generateCKEditor();
    editor.on('instanceReady', function(evt) {
        doSomeStuff();
        // There should be the resolve() of the promises I think.
    })
}

Maybe I have to do something like this:

function doSomeAsyncStuff() {
    var editor = generateCKEditor();
    return new Promise(function(resolve,refuse) {
        editor.on('instanceReady', function(evt) {
            doSomeStuff();
            resolve(true);
        });
    });
}

But I'm not sure of the syntax.

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]