【问题标题】:Javascript: Too many nested promisesJavascript:嵌套的承诺太多
【发布时间】:2018-09-25 04:26:11
【问题描述】:

我正在使用 Angular HttpClient 将一些数据存储在服务器中,但我遇到了一条重复的指令。保存过程如下:

if(client is new){
  //promise starts
  store client and retrieve id


  if(client has companion){
    //promise starts
    store companion and retrieve id

    //promise starts
    store product with previous retrieved id
  }
  //promise starts
  store product with only client id

}else{
  //promise starts
  store product 
}

正如您所见,“商店产品”指令重复了 3 次,因为我需要在继续之前从服务器返回信息。 以下是实际代码:

//Check if the client is new
    if (this.rent.client.id === 0) {

      this.clientServce.saveClientToDatabase(this.rent.client)
        .subscribe((results) => {
          //Store the new client Id
          this.rent.client.id = results.clientID;

          //Check if companion exists and save it to database
          if (this.rent.companion.id !== -1) {
            this.clientServce.saveCompanionToDatabase(this.rent.companion)
              .subscribe((companionResults) => {
                this.rent.companion.id = companionResults.clientID;

                //Save te rent
                this.rentServices.saveRentToDatabase(this.rent).subscribe()
              })
          } else {
            //Save te rent
            this.rentServices.saveRentToDatabase(this.rent).subscribe();
          }
        })
    } else {
      //Save te rent
      this.rentServices.saveRentToDatabase(this.rent).subscribe();

    }

它看起来确实可读。那么如何才能管理客户端和同伴存储并最终以可读的方式存储产品呢?

【问题讨论】:

  • 可能会解构this 以便属性名称变短
  • 1.那些不是承诺;您正在订阅,它们是可观察的。 2. 研究 observables 的操作符,你可以用一些地图把它弄平。

标签: javascript angular promise


【解决方案1】:

嵌套订阅块是一种反模式。因为您的代码容易受到多种竞争条件的影响。您正在操纵 http 调用之间的内部服务状态。这意味着,如果有多个对saveClientToDatabase 的快速连续调用,其中一些可能最终得到不正确的数据。

试试这样的方法:

import { mergeMap } from 'rxjs/operators';
import { of } from 'rxjs/observable/of';
import { forkJoin } from 'rxjs/observable/forkJoin';

const hasCompanion = this.rent.companion.id !== -1;
const rent = this.rent;

const saveClient$ = this.clientService.saveClientToDatabase(rent.client);
const saveCompanion$ = hasCompanion ? this.clientService.saveCompanionToDatabase(rent.companion) : of(null);

const saveRent$ = forkJoin([saveClient$, saveCompanion$]).pipe(mergeMap(([client, companion]: [any, any]) => {
  return this.rentServices.saveRentToDatabase(companion ? {
     ...rent,
     clientID: client.clientID,
     companion: companion.companionID
   } : {
     ...rent,
     clientID: client.clientID,
   })
}));

// single subscription and single manipulation of the internal state
saveRent$.subscribe(rent => this.rent = rent);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多