将 Promise 转换为 RxJs Observable

Posted

技术标签:

【中文标题】将 Promise 转换为 RxJs Observable【英文标题】:Convert Promise to RxJs Observable 【发布时间】:2018-02-19 11:16:15 【问题描述】:

有人可以帮助将这个 Promise 转换为 RxJs observable 吗? 我想从本地存储中获取令牌,如果出错,它应该被订阅 observable 的观察者捕获。以下是使用 Promise 的现有解决方案:

  getToken(): Promise<any> 
    return new Promise<any>((resolve, reject) => 
      resolve(JSON.parse(localStorage.getItem('currentUser')).token);
      reject();
    );
  

订阅者是:

 this.authService.getToken().then(token => 
      this.token = token;
    ).catch(() => console.log('Error! cannot get token'));

我尝试使用以下方法将其转换为 Observable:

 getToken2(): Rx.Observable<number> 
    return Rx.Observable.create(obs => 
      obs.next(JSON.parse(localStorage.getItem('currentUser')).token);
       obs.error('Error! cannot get token');
    );
  

  this.authService.getToken2()
  .subscribe((token) => console.log(token), (er) => console.log(er));

但问题是,当从 localstorage 获取令牌时发生错误时,RxJs observable 不会通过 obs.next() 捕获它。就像它已成功解决。而 Promise 通过拒绝方法成功捕获它。有人可以给出一个想法有什么问题?谢谢

【问题讨论】:

【参考方案1】:

你不需要做这一切,只需使用from()

import  from  from 'rxjs';

from(this.authService.getToken())
  ...
  .subscribe(...)

如果你想在 Observable 链中的任何地方使用 Promise,你甚至不需要将它转换为 Observable,因为它会自动发生。

https://medium.com/@benlesh/rxjs-observable-interop-with-promises-and-async-await-bebb05306875

2019 年 4 月:针对 RxJS 6 更新

【讨论】:

感谢 Martin 的回答。但我想将 getToken 方法本身转换为 Observable。我不想使用 Promise 或 fromPromise。你能写吗? 我不明白你想做什么。你根本不想使用 Promises 还是什么?你能做一个演示来展示你想要做什么吗? 没错。我根本不想使用 Promise。首先想用 Observable 写 getToken 而不是用 fromPromise 转换。然后订阅这个方法。 如果您认为catch 无法按预期工作,请进行演示。 getToken2 工作成功,但是当令牌未检索到时,obs.error() 不会发出错误,因此无法在订阅者中捕获错误。我调试并意识到应用程序成功(总是)解析 obs.next,因此没有实现 obs.error()。你能告诉我哪里错了吗?【参考方案2】:

您的getToken()-Method 应该有一些适当的错误处理。同时调用resolve()reject() 是不好的,并且可能导致意外行为。 最好这样做:

getToken(): Promise<any> 
  return new Promise<any>((resolve, reject) => 
    try 
      resolve(JSON.parse(localStorage.getItem('currentUser')).token);
    catch(err) 
      reject(err);
    
  );

话虽如此,getToken2() 也应该有适当的错误处理,例如:

getToken2(): Rx.Observable<number> 
  return Rx.Observable.create(obs => 
    try 
      obs.next(JSON.parse(localStorage.getItem('currentUser')).token);
    catch(err) 
      obs.error(err);
    
  );

【讨论】:

以上是关于将 Promise 转换为 RxJs Observable的主要内容,如果未能解决你的问题,请参考以下文章

Promise Chaining / Cascading to RxJS angular 1 to angular 2

RxJS Promise 组合(传递数据)

又开始了rxjs - 与promise的比较

RxJS Observables 的 Promise.all 行为?

RxJS之转化操作符 ( Angular环境 )

Angular:如何使用 RXJS 6 调用 finally()