仅当第一个Promise错误出现时,才如何返回其他Promise?

时间:2018-09-01 19:07:53

标签: angular angular-promise

具体情况是:

  • 我使用的是本地存储API,当您尝试“获取”值时会返回一个承诺。我要获取的值是一个自定义的“ UserProfile”对象。
  • 如果该值未定义或为null,那么我想通过Web请求进行http调用以获取UserProfile

也许我只是不太了解Promises。

这是我要执行的操作的无效代码,但我不知道语法的工作原理。

getUserProfile() {
  return this.storage.get("userProfile")
    .then(user => {
      if (user == null) {
        throw new Error("no user profile");
      }
    }
    )
    .catch(error => {
      //I don't know how to return a different promise
      return this.getUserProfileWithHttpCall();
    }
  );
}

//I want to return this in getUserProfile() if "userProfile" doesn't exist in "storage"
getUserProfileWithHttpCall(): Promise < UserProfile > {
  return this.http.get(this.baseUrl + "/Account/GetUserInfo")
    .toPromise()
    .then(
    response => {
      this.storage.set("userProfile", response);
      return response;
    }
  );
}

this.storage是“ @ ionic / storage”中的存储

this.http是HttpClient'@ angular / common / http'

1 个答案:

答案 0 :(得分:1)

对于您的想法,不需要抛出任何错误。您可以这样做:

getUserProfile() {
  return this.storage.get("userProfile")
    .then(user => user || this.getUserProfileWithHttpCall()
  );
}

或以awaitasync的方式:

async getUserProfile() {
  return (await this.storage.get("userProfile")) || this.getUserProfileWithHttpCall();
}

也许您想使用Observables,因为这些天来它们很时髦。您可以将其更改为此:

getUserProfile() {
  return from(this.storage.get("userProfile")).pipe(
    concatMap((user) => user ? of(user) : this.getUserProfileWithHttpCall())
  );
}

然后您必须更改getUserProfileWithHttpCall:

getUserProfileWithHttpCall(): Observable<UserProfile> {
  return this.http.get(`${this.baseUrl}/Account/GetUserInfo`).pipe(
    tap((user:UserProfile) => this.storage.set("userProfile", user))
  )
}

更加整洁:)

最后,要解释您的方法为什么行不通的原因是,如果您不希望如此“急剧”地更改代码,则在then不为null时不会返回用户,您也可以这样做:

getUserProfile() {
  return this.storage.get("userProfile")
    .then(user => {
      if (user == null) {
        throw new Error("no user profile");
      }

      return user; // you missed this one
    }
    )
    .catch(error => {
      //I don't know how to return a different promise
      // Like you already did
      return this.getUserProfileWithHttpCall();
    }
  );
}