【问题标题】:Guaranteeing a response from observable before execute next line在执行下一行之前保证来自 observable 的响应
【发布时间】:2019-03-09 19:39:09
【问题描述】:

我正在尝试等待来自 observable 的 API 调用,然后再继续执行下一行代码/函数。我无法做到这一点,但是 promise 可以与 await 一起使用。 到目前为止,这是我的代码:

 async validateDataObservable(email: string) {
    await this.userProfileService.getUserByEmail().subscribe((val: any) => {
      console.log('Hello');
    });
    console.log('Execute after Hello');

    // Output:
    // Execute after Hello
    // Hello
  }

不幸的是,这不是所需的输出行为。

下面的代码可以工作,但由于需要,我需要 Observables 相同的功能。

  async validateDataPromise(email: string) {
    await this.userProfileService.getUserByEmailPro(email).then((val: any) => {
      console.log('Hello');
    });
    console.log('Execute after Hello');

    // Output:
    // Hello
    // Execute after Hello
  }

感谢任何帮助。 谢谢

【问题讨论】:

  • 您不能将console.log('Execute after Hello'); 行放在then() 函数中吗?那么它总是在第一个函数之后执行。
  • 最简单的方法是在subscribe回调中移动console.log('Execute after Hello'),紧跟在console.log('Hello')之后。
  • 你可以使用toPromise(),但这意味着源 Observable 必须完成。

标签: angular typescript rxjs observable


【解决方案1】:

await 是一个 Promise 功能,所以很遗憾你不能用 Observables 做到这一点。如果你真的想要这个功能,你可以使用.toPromise(),但不推荐。您应该将代码放在 subscribe 正文中(或 map 中)。

【讨论】:

  • 为什么不推荐?
  • 因为 observables 更强大,如果不再需要它们可以取消。当然,在这里进行这种转换没有什么坏处,但你不应该让它成为一种习惯。这是不必要的开销,而且 IMO 也会使代码混乱。
【解决方案2】:

您可以使用 Behavior/Asyn Subject 并完整地编写代码。如下所示:

validateDataPromise(email: string) {
  this.userProfileService.getUserByEmailPro(email)
  .takeUntil(this.unSub)
  .subscribe((val: any) => {
    console.log('Hello');
  }, (error: Error) => {
    console.error('Error');
  }, () => {
    console.log('Execute after Hello');
  });
}

参考资料: https://medium.com/@luukgruijs/understanding-rxjs-behaviorsubject-replaysubject-and-asyncsubject-8cc061f1cfc0

http://reactivex.io/rxjs/manual/overview.html#asyncsubject

【讨论】:

    【解决方案3】:

    你不能那样做。将其余代码(您要在 console.log('hello') 之后执行的代码)获取到一个函数。并在调用后调用 subscribe 内部的函数 控制台日志('你好')。或者你可以在console.log('hello)之后把剩下的代码放在subscribe里面。

    async validateDataPromise(email: string) {
        await this.userProfileService.getUserByEmailPro(email).then((val: any) => {
          console.log('Hello');
          this.doRest()
        });
    
    
        // Output:
        // Hello
        // Execute after Hello
      }
    
    doRest(){
      console.log('Execute after Hello');
     // implement what you want after asynchronous call.
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-10
      • 1970-01-01
      • 2020-12-21
      • 2017-11-24
      • 2021-04-08
      • 1970-01-01
      相关资源
      最近更新 更多