【问题标题】:How do I blend a promise with an observable?如何将 promise 与 observable 混合?
【发布时间】:2020-02-02 20:30:18
【问题描述】:

我遇到了 promise 和 observables 的问题。我有一些使用 Promise 在包中定义的 http 请求。在我的其余代码中,我将 observables 用于各种事情,包括其他 http 调用。在一个特定部分中,我正在检查用户的不记名令牌是否已过期,如果是,我将获得一个新令牌,然后继续进行其余的通话。

if (!token || token.exp < Math.round((new Date()).getTime() / 1000)) {
  from(this._store.refreshBearerToken())
    .pipe(flatMap(resp => {
       let newToken = resp.data;
       newToken.exp = (new Date()).getTime() / 1000 + newToken.expires_in;
       localStorage.setItem('token', JSON.stringify(newToken))

       options = options || {};
       options.headers = new HttpHeaders({
         "Authorization": `${newToken.token_type} ${newToken.access_token}`,
         "Content-Type": "application/json"
        });
       return this._http$.request<T>(method, url, options as Object).pipe(share());
     }));
}

Bearer Token方法:

async refreshBearerToken() {
    const response = await this._q2.sources.requestExtensionData({
        route: "refreshBearerToken"
    });
    console.log(response);
    return response;
}

由于this._store.refreshBearerToken 返回一个承诺,我将调用包装在from 中以将其转换为可观察对象。这可以编译,但是当它运行时我得到“无法读取未定义的属性'管道'”。

如何将此 promise 转换为 observable,以便我可以刷新令牌,然后继续进行其余的调用?

编辑:

我正在通过import { Observable, from } from "rxjs"; 导入from

所以,我认为错误来自.pipe(flatMap(resp =&gt;... 行,但我错了。错误来自调用它的方法。

GetInitialLinkList(): Observable<Institution[]>
{
    let base = { 'MemberId': localStorage.getItem('memberId') };
    let ins = localStorage.getItem("initialInstitutionList");
    if (ins)
    {
        return of(JSON.parse(ins));
    }
    return this._settingsService.get().pipe(
        flatMap(settings =>
        {
            this._settings = settings;
            return this._api.request<Institution[]>("Post", `${this._settings.mea}/GetInitialLinkList`, { body: base })
                .pipe(
                    retry(1),
                    catchError(this.handleError)
                )
                .pipe(flatMap(instList =>
                {
                    localStorage.setItem("initialInstitutionList", JSON.stringify(instList));
                    return of(instList);
                }))
        }));
}

这是在我的组件中订阅的:

private GetLinkList()
{
    this.showWaiting.emit(true);
    this._data.GetInitialLinkList().subscribe((result) =>
    {
        this.initialList = result;
        this.showWaiting.emit(false);
    });
}

根据 Brandon 所说的(我忘了返回 /facepalm...)我添加了返回,所以我有 return from(this._store.refreshBearerToken()) 这将我的错误更改为

ERROR Error Code: undefined
Message: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
defaultErrorLogger @ core.js:6014

【问题讨论】:

  • 哪一行会报错? from 返回一个 Observable。
  • @martin 我添加了一些细节
  • 仅供参考,您应该使用 tap(x =&gt; sideEffect()) 而不是 flatMap(x =&gt; { sideEffect(); return of(x); })
  • 谢谢@Brandon,我去看看。
  • 否则,您仍然没有显示完整的代码示例。 handleError 是什么?您的原始代码实际上在哪里调用?您所有的原始代码都是代码片段。其余的方法在哪里?没有看到调用链中涉及的所有方法,这都是猜测。

标签: rxjs angular8 rxjs6


【解决方案1】:

您能否显示实际错误以及发生错误的代码行?同时显示您在何处以及如何导入from

我注意到你的代码 sn-p 没有返回它通过from(...).pipe(...) 建立的可观察对象,也没有订阅它。这可能有助于展示您的代码如何实际使用这个 observable。

【讨论】:

  • /facepalm 谢谢,我添加了退货,但我仍然收到错误。
  • 我的代码仍然需要一些工作,但主要是我缺少return。我的handleError 有问题,但这是一个不同的问题。感谢您对此的帮助。
猜你喜欢
  • 2018-12-14
  • 2019-05-31
  • 2016-07-15
  • 2018-02-09
  • 1970-01-01
  • 2021-12-01
  • 2016-05-09
  • 2021-06-23
  • 2017-04-04
相关资源
最近更新 更多