【问题标题】:Subscribe call within a forEach loop executes too lateforEach 循环中的订阅调用执行得太晚
【发布时间】:2019-04-08 11:55:48
【问题描述】:

为什么控制台日志最后会显示所有“if”输出?

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

我期待输出:

elem
if 
elem 
else ...

我认为它会在每个“elem”之后显示“if”或“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('');
    }
});

【问题讨论】:

  • 完全取决于res.docs的内容,不过帖子中没有显示。另外,如果Service 是异步的……等等! Service 是否有一个名为 function.. 的方法?
  • 发布res.docs里面的内容
  • .subscribe() 可能是一个异步函数
  • 你必须从异步响应中取出console.log('if');,否则所有forEach循环在开始记录它们时都会结束
  • 请注意,您的 this.marketPlaceList 数组将按照您预期的顺序排列

标签: javascript if-statement foreach


【解决方案1】:

由于 observable 异步发出事件,您的 forEach 循环将在执行任何对 .subscribe 的回调之前完成。

您可以通过将 observable 转换为 Promise 并 await-ing 来解决这个问题。要使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 

当您需要完全填充 this.marketPlaceList 数组时,请务必等待最外层的 async 函数(或在其上使用 then)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 2014-05-12
    • 1970-01-01
    相关资源
    最近更新 更多