1. ホーム
  2. javascript

[解決済み] たくさんのPromiseを返して、他のことをする前に全部待つ方法

2022-10-10 18:50:39

質問

非同期に何かを行うメソッドを呼び出すループがあります。このループはメソッドを何度も呼び出すことができます。このループの後に、すべての非同期的なものが完了したときにのみ実行される必要がある別のループを持っています。

これは私が欲しいものを示しています。

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

でも、構文がよくわからない。

どのように解決するのですか?

この場合 Promise.all ( スペック , MDN ) を使うことができます。それは個々の約束の束を受け入れ、あなたが与えた約束のすべてが解決されたときに解決され、それらのいずれかが拒否されたときに拒否される単一の約束をあなたに返します。

ですから、もしあなたが doSomeAsyncStuff はプロミスを返すとします。

    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にはプロミスに関する記事があります はこちら . また、私の本の第8章では、プロミスを詳しく取り上げています。 JavaScriptで詳しく説明しています。新しいおもちゃ もし興味があれば、私のプロフィールにリンクがあります。

これはその一例です。

 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();

出力例(出力に Math.random があるため、最初に終わるものは異なる場合があります)。

3を解決する
2を解決する
1を解決する
リゾルブ4
0を解決する
すべて完了[0,1,2,3,4]。