【问题标题】:How to add items to an array outside promise如何将项目添加到承诺之外的数组
【发布时间】:2020-07-02 15:36:09
【问题描述】:

这个疑问是关于承诺的。 我需要将子集合'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 方法有“等待”。

【问题讨论】:

  • get() 也是异步的并返回一个承诺。您将无法在 forEach 循环中使用 await。您将需要另一种策略。见:stackoverflow.com/questions/37576685/…
  • 谢谢,我用 Promise.all(...) 试过了,效果很好

标签: javascript firebase foreach promise async-await


【解决方案1】:

您做错的主要是期望异步.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(...)

【讨论】:

    猜你喜欢
    • 2015-03-26
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 2011-07-01
    • 1970-01-01
    相关资源
    最近更新 更多