Подтвердить что ты не робот

Как вернуть много Promises в цикле и ждать, пока они все сделают другие вещи

У меня есть цикл, который вызывает метод, который делает вещи асинхронно. Этот цикл может вызывать метод много раз. После этого цикла у меня есть еще один цикл, который должен выполняться только после выполнения всех асинхронных операций. Итак, это иллюстрирует то, что я хочу:

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

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

Я не очень знаком с обещаниями, может ли кто-нибудь помочь мне в этом?

Вот как ведет себя мой doSomeAsyncStuff():

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

Может быть, я должен сделать что-то вроде этого:

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

Но я не уверен в синтаксисе.

4b9b3361

Ответ 1

Вы можете использовать Promise.all (spec, MDN) для этого: он принимает кучу отдельных promises и возвращает вам одно обещание, которое разрешается, когда все те, которые вы ему дали, разрешены или отклоняются, когда кто-либо из них отклоняется.

Итак, если вы вернете обещание doSomeAsyncStuff, то:

var promises = [];

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

Promise.all(promises)
    .then(() => {
        for(i=0;i<5;i+){
            doSomeStuffOnlyWhenTheAsyncStuffIsFinish();    
        }
    })
    .catch((e) => {
        // handle errors here
    });

Axel Rauschmayer имеет хорошую статью о promises здесь.

Вот пример - живая копия на Babel REPL:

 function doSomethingAsync(value) {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log("Resolving " + value);
          resolve(value);
        }, Math.floor(Math.random() * 1000));
      });
    }
    
    function test() {
      let i;
      let promises = [];
      
      for (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();