Как добавить элементы в массив вне обещания - PullRequest
0 голосов
/ 21 марта 2020

это сомнение по поводу обещаний. Мне нужно добавить документы вложенной коллекции 'bar' в массив, инициализированный за пределами блока

...
foo.bars = new Array<IBar>();
let manyBars = documentRef.collection('bar').listDocuments();
(await manyBars).forEach( barItem => {
    barItem.get().then(barDocument => {

        let bar: IBar = JSON.parse(JSON.stringify(barDocument.data()));
        if (foo.bars !== null) {
            foo.bars.push(bar);
            console.log('in');
        }
    });
});

console.log('out');

Мой console.log () выводит первый вывод 'out', а затем 'in'. Что я делаю неправильно? У метода forEach есть «await».

1 Ответ

1 голос
/ 22 марта 2020

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

Хотя await является просто синтаксической альтернативой для .then(), она в значительной степени позволяет писать асинхронный код в той же степени, что и это было бы, если бы оно было синхронным.

Как правило, в любой заданной функции рекомендуется не смешивать синтаксис .then() и await

Предполагая, что barDocument.data() является синхронным, все должно быть так просто ...

...
try{
    let manyBars = await documentRef.collection('bar').listDocuments();
    let barDocuments = await Promise.all(manyBars.map(barItem => barItem.get()));
    let foo.bars = barDocuments.map(barDocument => barDocument.data());
}
catch(error) {
    console.log(error);
    // handle error as necessary.
    // return a value or re-throw the error.
}

Если barDocument.data() является асинхронным, то вам нужно будет ввести еще один await Promise.all(...).

...