Как я могу вернуть другое Обещание только в том случае, если возникли первые ошибки Обещания? - PullRequest
0 голосов
/ 01 сентября 2018

Особая ситуация:

  • Я использую API локального хранилища, которое возвращает обещание, когда вы пытаетесь «получить» значение. Значение, которое я пытаюсь получить, является пользовательским объектом "UserProfile".
  • Если значение не определено или равно нулю, я хочу сделать http-вызов для получения UserProfile с помощью веб-запроса

Может быть, я просто недостаточно хорошо понимаю Обещания.

Вот нерабочий код того, что я хочу сделать, но я не знаю, как работает синтаксис.

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 голосов
/ 01 сентября 2018

По вашей идее, нет необходимости выдавать какую-либо ошибку. Вы можете сделать это:

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

Или await, async:

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, когда он не равен нулю, если вы не хотите изменять свой код так «радикально», вы можете также просто сделайте это:

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();
    }
  );
}
...