Angular жду не жду - PullRequest
       6

Angular жду не жду

2 голосов
/ 23 января 2020

У меня есть немного кода с await -s, установленным так:

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 ]

1 голос
/ 23 января 2020

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

Если нет, пожалуйста, отредактируйте свой пост, и я постараюсь предложить другое решение.

1 голос
/ 23 января 2020

Вам необходимо использовать 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().

Поскольку Похоже, вы отбрасываете результаты внешних обещаний, тогда я не вижу здесь реальной проблемы с заказом. Вы просто хотите запустить некоторый код после того, как все будет сделано.

1 голос
/ 23 января 2020

await не будет работать для циклов, которые используют обратные вызовы. Никогда не используйте await с forEach. Используйте for-l oop (или любой l oop без обратного вызова) вместо

forEach без учета обещаний. Он не может поддерживать asyn c и ждать. Вы не можете использовать await в forEach.

Узнать больше ...

...