在Angular 8中,异步/等待(Async/await)不按预期工作。

3

我习惯于在Asp.net中使用async/await。现在我需要在ngBootstrap Modal Service中进行多个API调用(4个)。用户将单击一个按钮以打开模态框。第一个API调用获取模态框所需的基本信息。异步的OpenModal()方法被标记为async,第一个API调用使用了async res,如下所示。

this.service.findContent(id).subscribe(
          async res => { 

  //other code 

  var socialDataResult = await this.getSocialData();
  console.log('socialDataResult ', socialDataResult);

  //other code

},


async getSocialData() {

        let result: SocialData;

        this.socialDataService.findSocialData().subscribe(
          async res => {

            let socialData = new SocialData(res);
            console.log('socialData ', socialData);

            result = socialData;
            return result;

          },
          err => {

            console.log(err);
          }
        )

        return result;

      }

我希望代码在调用 getSocialData 后等待返回响应再写入控制台。目前,它会在调用方法下方写入控制台日志,然后才会在被调用的方法中写入控制台日志。调用方法中的控制台日志显示“undefined”。被调用方法中的控制台日志则显示包含所有数据的 SocialData 对象。
同时需要注意的是,当我将鼠标悬停在 await this.getSocialData(); 上时,会得到以下信息。
(method) ContentComponent.getSocialData(): Promise<SocialData>

非常感谢任何帮助。谢谢!


1
subscribe() 函数期望传入一个回调函数作为参数,该回调函数将接收到的事件作为参数,并且不返回任何值。无论你从回调函数中返回什么都会被忽略。nothing 将在你从回调函数返回的 promise 上调用 then()。我强烈建议你学习如何使用 observables,并在此基础上构建,而不是将它们与 promises 混合使用。 - JB Nizet
2个回答

5

getSocialData被标记为async,但实际上却没有等待任何东西。如果你并未利用Observable的高级特性,那么最好将findSocialData()的结果转换为Promise。

async getSocialData() {

    try {
        let res = await this.socialDataService.findSocialData().toPromise();
        let socialData = new SocialData(res);
        console.log('socialData ', socialData);
        return socialData;
    } catch(err) {
        console.log(err); // you might not actually want to eat this exception.
    }
}

你的解决方案很有效,而且速度非常快。非常感谢! - Dumber_Texan2

1
我认为你混淆了使用Observables和async/await。对于你的用例,我建议你只使用Observables。看起来你有多个链接的调用,Observables可以帮助你组织调用并以你想要的方式获取响应。
你可以查看我的stackblitz,我有一个处理嵌套订阅的解决方案。

https://stackblitz.com/edit/rxjs-learnings?file=nested-subscribe.ts

在这里处理Observables将是一个优雅的解决方案。


此外,还有一些关于Observables的好教程,你可能想要关注一下。 - Sanket
我喜欢你提出的解决方案,它对我很有意义。使用你的方法,如果要等待另一个对象获取ID以便进行另一个API调用,该怎么办呢?此外,你如何读取数据?我想你的Observable里可能会有几个对象。感谢你优雅的解决方案! - Dumber_Texan2
1
请查看我的答案,链接如下:https://stackoverflow.com/questions/57562159/angular-7-how-to-re-write-nested-subscribtions/57567909#57567909。在进行另一个API调用时,您可以从第一个API的响应中读取数据,并对其进行任何中间响应的处理。 - Sanket

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接