如何等待for循环的多个异步调用?

时间:2018-09-11 13:03:14

标签: node.js promise async-await es6-promise ecmascript-2017

没有任何处理的代码:

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

在上面的代码中,imgDownloadasync function,它将下载图像,match将已下载图像的功能与另一个图像进行匹配。 for-loop之后需要执行一个功能。

如何使用Promiseasync-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 :(得分:3)

在上一次更新中,尽管您在async-await中使用了for-loop,但这并没有阻止您的同步流。

我假设您的imgDownloadmatch函数正在返回promise。

然后新的代码将是:

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

答案 1 :(得分:0)

感谢大家的评论。

func rxLogin() {

    let isValidPassword = username.rx.text.orEmpty
        .map { $0.count > 8 }
        .distinctUntilChanged()

    let isValidEmail = password.rx.text.orEmpty
        .map { $0.contains("@") }
        .distinctUntilChanged()

    let isButtonEnabled: Observable<Bool> = Observable.combineLatest(isValidEmail, isValidPassword) { $0 && $1 }.share()

    //option 1

    let submitButtonState: BehaviorRelay<Bool> = BehaviorRelay<Bool>(value: false)

    isButtonEnabled
        .bind(to: submitButtonState)
        .disposed(by: disposeBag)

    submitButtonState
        .bind { (isEnabled) in
            self.loginButton.isEnabled = isEnabled
            self.loginButton.backgroundColor = isEnabled ? UIColor.green : UIColor.red
        }.disposed(by: disposeBag)

    //OR

    isButtonEnabled
        .subscribe(onNext: { (isValidCredentials) in
            self.loginButton.isEnabled = isValidCredentials
            self.loginButton.backgroundColor = isValidCredentials ? .green : .red
        }).disposed(by: disposeBag)
}

这是有效的- (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"); })(); 仅在for循环之后显示。


如以上答案中所述使用"After forEach"时。

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下时,这应该是原因。