将嵌套的rxjs conf缩放到aysnc-wait?

发布于 2025-02-05 05:04:15 字数 1101 浏览 3 评论 0原文

我总是遇到嵌套的con缩,后者的HTTP请求基于前一个结果。 请参阅下面的示例,我需要获取FormConfig,然后使用FormConfig ID获取应用程序记录,然后获取XXX。它是否更可读取和可维护的转动嵌套的RXJS辅助映射到Aysnc等待( 避免回调地狱 )?优点和缺点?哪一个更容易处理错误处理?

一般嵌套concatmap

  ngOnInit(){
     this.http.get(`/app-config/${this.appType}`)
     .pipe(
         concatMap(formConfig => {
             this.formConfig = formConfig;
             return this.http.get(`/appl/${this.formConfig.id}`);
         }),
         concatMap(applRec => {
             this.applRec = applRec;
             return this.http.get(`/xxx/${this.applRec.recNo}`)          
         })
        tap((val) => {this.xxx = val})
         ....
     ).subscribe();
  }

转向异步等待topromise

 constructor(){
   this.init().then();
 }
 async init() {
    this.formConfig = await this.http.get(`/app-config/${this.appType}`).toPromise();
    this.applRec = await this.http.get(`/appl/${this.formConfig.id}`).toPromise();
    this.xxx = await this.http.get(`/xxx/${this.applRec.recNo}`).toPromise();
  }

I always encounter nested concatMap, the latter http requests base on the former results.
See below example, I need get formConfig and then use the formConfig id to get application record, then xxx. Is it more readable and maintainable turning nested rxjs concatMap to aysnc await (Avoid callback hell)? Pros and cons? which one is easier to process error handling?

General nested concatMap

  ngOnInit(){
     this.http.get(`/app-config/${this.appType}`)
     .pipe(
         concatMap(formConfig => {
             this.formConfig = formConfig;
             return this.http.get(`/appl/${this.formConfig.id}`);
         }),
         concatMap(applRec => {
             this.applRec = applRec;
             return this.http.get(`/xxx/${this.applRec.recNo}`)          
         })
        tap((val) => {this.xxx = val})
         ....
     ).subscribe();
  }

Turn to async await toPromise

 constructor(){
   this.init().then();
 }
 async init() {
    this.formConfig = await this.http.get(`/app-config/${this.appType}`).toPromise();
    this.applRec = await this.http.get(`/appl/${this.formConfig.id}`).toPromise();
    this.xxx = await this.http.get(`/xxx/${this.applRec.recNo}`).toPromise();
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

这个俗人 2025-02-12 05:04:15

topRomise()已弃用并正在删除,因此您可能应该避免使用它。有关此信息的更多信息: https://indepth.dev/posts/1287/rxjs-heads-up-tpromise-is-is-being-deprecated#why-is-is-is-is-thisthis-the-thappening-to-to-to-to-to-to-to-me

如果要使用async/等待/承诺您可以使用firstValueFrom()。在此处的文档中概述了使用它的缺点: https://rxjs.dev/api/索引/函数/firstValuefrom

警告:仅将其与您知道的可观察物一起使用,至少会发出一个值或完成。如果可观察到的源没有发出一个值或完成一个值,您最终会得到挂断的承诺,并且可能是在内存中悬挂的异步函数的所有状态。为了避免这种情况,请考虑添加超时,拿走,采取或在其他情况下添加。

因此,承诺的缺点是您需要添加超时或冒着内存泄漏的风险。但是,我认为当使用HTTPCLIENT服务的观察力时,您不必担心这一点,我从未见过一个人没有发出值或完整的值。

由于您只是在寻找单个值而不是可观察到的流,因此在这里使用承诺的任何缺点。您也可以将ngoninit标记为async

  async ngOnInit() {
    this.formConfig = await firstValueFrom(this.http.get(`/app-config/${this.appType}`));
    this.applRec = await firstValueFrom(this.http.get(`/appl/${this.formConfig.id}`));
    this.xxx = await firstValueFrom(this.http.get(`/xxx/${this.applRec.recNo}`));
  }

toPromise() is deprecated and is being removed, so you should probably avoid it. More info on that here: https://indepth.dev/posts/1287/rxjs-heads-up-topromise-is-being-deprecated#why-is-this-happening-to-me.

If you want to use async / await / promises you can use firstValueFrom(). The cons of using it are outlined in the docs here: https://rxjs.dev/api/index/function/firstValueFrom

WARNING: Only use this with observables you know will emit at least one value, OR complete. If the source observable does not emit one value or complete, you will end up with a promise that is hung up, and potentially all of the state of an async function hanging out in memory. To avoid this situation, look into adding something like timeout, take, takeWhile, or takeUntil amongst others.

So the disadvantage of promises is that you need to add a timeout or you risk a memory leak. However, I don't think you have to worry about this when using the observables from the HttpClient service, I've never seen one not emit a value or complete.

Since you're only looking for single values and not observable streams, I don't see any downside to using promises here. You can also just label ngOnInit as async.

  async ngOnInit() {
    this.formConfig = await firstValueFrom(this.http.get(`/app-config/${this.appType}`));
    this.applRec = await firstValueFrom(this.http.get(`/appl/${this.formConfig.id}`));
    this.xxx = await firstValueFrom(this.http.get(`/xxx/${this.applRec.recNo}`));
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文