Как ждать нескольких асинхронных вызовов из цикла for? - PullRequest
0 голосов
/ 11 сентября 2018

Код без какой-либо обработки:

  for (i=0; i<dbImgCount; i++){
        (function(i) {
             imgDownload(FolderPath[i].FolderPath, function (next){
                var url = FolderPath[i].FolderPath;
                const img2 = cv.imread(imgDownload.Filename);
                match({url,
                    img1,
                    img2,
                    detector: new cv.ORBDetector(),
                    matchFunc: cv.matchBruteForceHamming,
                });

            })
        })(i);
      }

В приведенном выше коде imgDownload - это асинхронная функция , которая будет загружать изображение, match будет сопоставлять функции загруженного изображения сдругое изображение.После этого нужно выполнить функцию for-loop.

Как реструктурировать этот код, используя Promise или async-await, чтобы каждый вызов асинхронной функции ожидался, а только после завершенияfor-loop, поток продолжается?


Отредактировал код с помощью async-await:

    FolderPath.forEach(FolderPath => {
        (async function () {
            var filename = await imgDownload(FolderPath.FolderPath);
            var url = FolderPath.FolderPath;
            const img2 = cv.imread(filename);
            imgs = await match({url,
                img1,
                img2,
                detector: new cv.ORBDetector(),
                matchFunc: cv.matchBruteForceHamming,
            });
        })();
    });

    function someFunction(){
       console.log("After forEach");
    }

Как выполнить someFunction только послеforEach

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Спасибо всем за комментарии.

   (async function () { 
        for (i = 0; i < FolderPath.length; i++) {
            var filename = await imgDownload(FolderPath[i].FolderPath);
            var url = FolderPath[i].FolderPath;
            const img2 = cv.imread(filename);
            imgs = await match({url,
                img1,
                img2,
                detector: new cv.ORBDetector(),
                matchFunc: cv.matchBruteForceHamming,
            });
        }
        console.log("After forEach");
    })();

Это рабочий - "After forEach" отображается только после цикла for.


При использовании forEach, как указано в ответе выше.

(async function () {

   // Next loop won't be executing without completing last.
  FolderPath.forEach(FolderPath => {

    var filename = await imgDownload(FolderPath.FolderPath);
    var url = FolderPath.FolderPath;

    const img2 = cv.imread(filename);

    imgs = await match({url,
        img1,
        img2,
        detector: new cv.ORBDetector(),
        matchFunc: cv.matchBruteForceHamming,
    });
});

// Now will wait for for-loop to end
function someFunction(){
   console.log("After forEach");
}
// End of async-await
})();

Вывод - SyntaxError: await is only valid in async function.

Я думаю, что ключевое слово await не будет входить в область действия функции async, когда оно входит в forEach, это должно быть причиной.

0 голосов
/ 12 сентября 2018

С вашим последним обновлением, хотя вы использовали async-await внутри for-loop, но это не остановило ваш синхронный поток.

Я предполагаю, что ваши imgDownload и match функциивозвращение обещания.

Тогда новый код будет:

(async function () {

    // Next loop won't be executing without completing last.
    for (i = 0; i < FolderPath.length; i++) {

        var filename = await imgDownload(FolderPath[i].FolderPath);
        var url = FolderPath[i].FolderPath;

        const img2 = cv.imread(filename);

        imgs = await match({url,
            img1,
            img2,
            detector: new cv.ORBDetector(),
            matchFunc: cv.matchBruteForceHamming,
        });
    }

    // Now will wait for for-loop to end
    function someFunction(){
       console.log("After forEach");
    }
// End of async-await
})();

Вот небольшой пример:

(async function () { 
    for (i=0; i<5; i++) {
        x = await main();
        console.log(x, i);
    }
    console.log("Finally");
})();

// asynchronous main function
function main() {
    return new Promise( (resolve, reject) => {
        setTimeout(()=> { resolve('Done'); }, 5000)
    });
}
...