角等待不等待

时间:2020-01-23 15:39:26

标签: angular promise async-await

我有一些设置为await-的代码,如下所示:

async calculateDeletionResidualsData(res) {
    //console.log("resss is:");
    //console.log(res);

    let selectedCountries = this.countriesList.filter(c => c.selected);
    let selectedIndicators = this.indicatorsList.filter(i => i.selected);

    await selectedCountries.forEach(async c => {
        // taking each (selected) country

        await selectedIndicators.forEach(async i => {
            // taking each (selected) indicator

            // Form the series for the calculation of residuals
            let series = [];
            deletionResidualsRelevantYears.forEach(y => {
                series.push(res[c.label][y][i.label][0]);
            });
            // Calculate deletion residuals
            let drr = await util.calculateDeletionResidualsStatistics(
                deletionResidualsRelevantYears.length,
                series,
                this.deletionResidualsService
            );

            this.drr[c.label][i.label] = drr;
        });
    });

    console.log("setting qrReady to true");
    this.qrReady = true;
}

我可以清楚地看到对util.calculateDeletionResidualsStatistics的调用仍在浏览器的“网络”标签中进行,但是我也看到console.log("setting qrReady to true");已被触发,因此不应该被辞退了。为什么所有这些等待的内容都被跳过并跳到了最后一行代码?

3 个答案:

答案 0 :(得分:1)

await不适用于使用回调的循环。永远不要将forAeach与await一起使用。改为使用for循环(或任何没有回调的循环)

forEach不支持诺言。它不支持异步和等待。您不能在forEach中使用await。

Learn more...

答案 1 :(得分:1)

await仅适用于返回Promise的函数。 forEach没有。 假设util.calculateDeletionResidualsStatistics返回一个Promise,而是这样编写代码:

calculateDeletionResidualsData(res) {
    //console.log("resss is:");
    //console.log(res);

    let selectedCountries = this.countriesList.filter(c => c.selected);
    let selectedIndicators = this.indicatorsList.filter(i => i.selected);

    selectedCountries.forEach( c => {
        // taking each (selected) country

        selectedIndicators.forEach(async i => {
            // taking each (selected) indicator

            // Form the series for the calculation of residuals
            let series = [];
            deletionResidualsRelevantYears.forEach(y => {
                series.push(res[c.label][y][i.label][0]);
            });
            // Calculate deletion residuals
            let drr = await util.calculateDeletionResidualsStatistics(
                deletionResidualsRelevantYears.length,
                series,
                this.deletionResidualsService
            );
            this.drr[c.label][i.label] = drr;
        });
    });

    console.log("setting qrReady to true");
    this.qrReady = true;
}

如果没有,请编辑您的帖子,我将尝试提供其他解决方案。

答案 2 :(得分:1)

如果您有一组诺言,则需要将Promise.all()await一起使用,并使用map()操作来创建诺言数组。

    await Promise.all(selectedCountries.map(async c => {
        await Promise.all(selectedIndicators.map(async i => {
            let drr = await util.calculateDeletionResidualsStatistics(...);
            // ...
        });
    });

    console.log('printed after everything is finished');

请记住,Promise.all()将在所有内部承诺都解决之后解决一系列结果。这些承诺的顺序在并行解决时是无法预测的。

您最终将得到嵌套的Promise.all(),它将在顶级Promise.all()解析之前分批解析。

由于您似乎正在舍弃外部承诺的结果,因此我在这里看不到订单的真正问题。您只想在完成所有操作后运行一些代码。