Javascript:太多嵌套的承诺

时间:2018-04-15 09:02:01

标签: javascript angular promise

我正在使用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 
}

正如您所看到的,“存储产品”指令重复三次,因为我需要在继续操作之前从服务器返回信息。 这是实际的代码:

//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();

    }

看起来确实可读。那么怎样才能以可读的方式管理客户端和同伴存储和存储产品呢?

1 个答案:

答案 0 :(得分:1)

嵌套订阅块是一种反模式。因为您的代码容易受到多种竞争条件的影响。您正在操纵http调用之间的内部服务状态。这意味着,如果快速连续向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); 发出多个调用,其中一些调用可能最终会导致数据不正确。

尝试这样的事情:

<!DOCTYPE html>
<html>
<head>
    <title>myFb</title>
     <link rel="stylesheet" type="text/css" href="style1.css">
    <script src="https://s3.amazonaws.com/stitch-sdks/js/library/v3/stable/stitch.min.js"></script>
    <script src="assig02.js"></script>

</head>
<body onload="onLoadConnectDB()">


<p>Hello My App</p>

<div id="wlcom" align="center">
    <button name="adding" onclick="addUser()">Add User</button><br>
    <button name="deleting" onclick="deleteUser()">Delete User</button> <br>
    <button name="logging" onclick="loginUser()">Login</button><br>
</div>


</body>
</html>