【问题标题】:How to return Observable after some Promise get resolved in Ionic 2/Angular 2?在 Ionic 2/Angular 2 中解决某些 Promise 后如何返回 Observable?
【发布时间】:2017-05-25 22:15:29
【问题描述】:

我试图在成功完成我的 Promise 后返回一个 observable,但该函数没有返回 Observable。 具体到代码,我想从存储中获取身份验证令牌(返回承诺),然后在获取数据之后生成对 Api 的 Post 请求(返回 Observable)。通过这样做,sublime text 在函数上给出一个错误,“声明类型既不是'void'也不是'any'的函数必须返回一个值” 下面是我的代码,

logout() : Observable<any>{
  this.userData.getAuthToken().then((token)=>{
    this.token = token;
    this.headers = new Headers ({
      "X-USER-TOKEN": token
    });
    this.options = new RequestOptions ({
      headers: this.headers
    });
    var logout_url = "Api logout method";
    return this.http.post(logout_url,{},this.options)
      .map (res => res.json())
  });
}

如果我只是做一个发布请求,那么它会像这样返回正常

return this.http.post(logout_url,{},this.options)
  .map (res => res.json())

但是当我尝试获取数据时,它不会从此发布请求中返回值。 任何帮助都感激不尽!在此先感谢

【问题讨论】:

    标签: angular ionic2 angular2-services


    【解决方案1】:

    您将返回 Promise(如果您没有错过前面的 return 部分),成功时将返回 Observable。考虑只使用Observables,而不是同时使用它们。

    您也可以将其封装成一个新的Observablenew Observable(observer =&gt;
    https://angular-2-training-book.rangle.io/handout/observables/using_observables.html

    【讨论】:

    • 承诺返回一个可观察的,真实的..但是logout没有返回任何东西..
    • 是的,ionic 2 存储返回成功从存储中检索数据的承诺,然后 angular 2 http post 方法返回 Observable。主要的是,我怎样才能直接从内部承诺成功返回一些东西?虽然你能分享一下只转换为 Observable 的代码 sn-p 吗?它可能有助于解决问题。
    • @M.Habib 承诺是异步的,您已经返回了 Observable,但您仍然需要等待 Promise 完成。您可以执行我链接的示例中显示的操作,也可以查看@cartant 答案。
    • @zurfyx 你能解释一下为什么 promise 返回 observable。我期望返回 new Promise((resolve, reject) => {});返回 Promise 但返回 Observable。
    【解决方案2】:

    使用fromPromise 将promise 转换为可观察对象,并使用mergeMap 将HTTP 响应发送到组合的可观察对象中:

    import { Observable } from 'rxjs/Observable/';
    import 'rxjs/add/observable/fromPromise';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/mergeMap';
    
    logout(): Observable<any>{
      return Observable.fromPromise(this.userData.getAuthToken()).mergeMap(token => {
        this.token = token;
        this.headers = new Headers({
          "X-USER-TOKEN": token
        });
        this.options = new RequestOptions({
          headers: this.headers
        });
        var logout_url = "Api logout method";
        return this.http.post(logout_url, {}, this.options).map(res => res.json());
      });
    }
    

    【讨论】:

    • 这个解决方案看起来不错,但它给出了一个错误提示 TypeError: Observable_2.fromPromise is not a function。 虽然我发布了我的函数的简写版本。用 fromPromise 和 mergeMap 更新后的函数贴在上面。请看一下它看起来不错吗?
    • 在答案中添加了必要的导入。
    【解决方案3】:

    RXJS>6 时,fromPromise 合并到from 函数中,要使用mergeMap,需要先使用pipe。所以这段代码可以工作

        import { Observable, from } from "rxjs";
        import { map, mergeMap } from "rxjs/operators";
        
        logout(): Observable<any>{
          return from(this.userData.getAuthToken()).pipe(mergeMap(token => {
            this.token = token;
            this.headers = new Headers({
              "X-USER-TOKEN": token
            });
            this.options = new RequestOptions({
              headers: this.headers
            });
            var logout_url = "Api logout method";
            return this.http.post(logout_url, {}, this.options).map(res => res.json());
          }));
        }
    

    【讨论】:

      【解决方案4】:

      Sunil 的回答适用于我的用例,这是我的工作示例。我在我的 http 拦截器中使用它来将访问令牌附加到 HTTP 请求

      import {from, Observable} from "rxjs";
      import {mergeMap} from "rxjs/operators";
      
       handleTokenExpiration(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
          if (this.isAccessTokenPresent()) {
            request = request.clone({
              setHeaders: {
                Authorization: `Bearer ${this.getAccessToken()}`
              }
            });
            return next.handle(request);
          } else {
            if (this.isRefreshTokenPresent()) {
              return from(this.refreshToken(this.getRefreshToken())).pipe(mergeMap(res => {
                request = request.clone({
                  setHeaders: {
                    Authorization: `Bearer ${this.getAccessToken()}`
                  }
                });
                return next.handle(request);
              }));
            } else {
              this.logout();
            }
          }
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-25
        • 1970-01-01
        • 2017-11-16
        • 1970-01-01
        • 2016-12-28
        • 2018-07-14
        • 2017-09-25
        • 1970-01-01
        相关资源
        最近更新 更多