Вызов подписки внутри цикла forEach выполняется слишком поздно - PullRequest
0 голосов
/ 08 апреля 2019

Почему в конце журнала консоли отображаются все выходные данные «если»?

3 elem :
else
elem :
else
elem :
else
elem :
else
2 elem :
4 if

Я ожидал вывода:

elem
if 
elem 
else ...

Я думал, что он будет показывать «если» или «еще» сразу после каждого «элемента»!

Вот код:

res.docs.forEach((elem) => {
    console.log('elem');
    if (elem.productType) {
        this.Service.function(elem.productType._id).subscribe((result) => {
            console.log('if');
            const text = result.name;
            this.marketPlaceList.push(text);
        });
    } else {
        console.log('else');
        this.marketPlaceList.push('');
    }
});

1 Ответ

2 голосов
/ 08 апреля 2019

Поскольку наблюдаемое генерирует события асинхронно, ваш цикл forEach завершится до того, как будет выполнен любой обратный вызов .subscribe.

Вы можете решить эту проблему, превратив наблюдаемое в обещание, и awaitэтоЧтобы await работал, вам нужна функция async, поэтому сверните ваш код в такую ​​функцию и замените цикл forEach на цикл for:

(async () => { // Async wrapper
    for (const elem of res.docs) { // Use for-loop
        console.log('elem');
        if (elem.productType) {
            // Convert observable to promise, and await
            const result = await this.Service.function(elem.productType._id).toPromise();
            console.log('if');
            const text = result.name;
            this.marketPlaceList.push(text);
        } else {
            console.log('else');
            this.marketPlaceList.push('');
        }
    }
)(); // execute immediately 

Обязательнотакже дождитесь самой внешней функции async (или используйте на ней then), когда вам нужно заполнить массив this.marketPlaceList.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...