在 Promise 中返回 Observable

Posted

技术标签:

【中文标题】在 Promise 中返回 Observable【英文标题】:Return Observable inside the Promise 【发布时间】:2018-11-25 05:04:32 【问题描述】:

你能告诉我如何在这里返回Observable吗?我尝试了很多方法。但还没有成功。

[ts] 声明类型既不是“void”也不是“any”的函数必须 返回一个值。

  deleteInvite(inviteId):Observable<HttpResponse<Object>> 
    this.getHttpHeader().then(headers => 
      return this.http.post(this.apiURL + "/deleteInvite", inviteId,  observe: "response", headers: headers )
    ).catch(err => 
      console.error(err);
    );
  

  async getHttpHeader() 
    const accessToken = await this.getJWTToken();
    let headers = new HttpHeaders().set('Authorization', `Bearer $accessToken`);
    return headers;
  

【问题讨论】:

return this.getHttpHeader().then ... 上面写着:[ts] Type 'Promise&lt;void | Observable&lt;HttpResponse&lt;Object&gt;&gt;&gt;' is not assignable to type 'Observable&lt;any&gt;'. Property '_isScalar' is missing in type 'Promise&lt;void | Observable&lt;HttpResponse&lt;Object&gt;&gt;&gt;'.@bugs learnrxjs.io/operators/creation/frompromise.html @Sampath 这是一个不同的问题,请参阅发布的链接 任何帮助如何在我的用例中使用它? @DeblatonJean-Philippe 【参考方案1】:

getHttpHeader() 返回一个Promise。只是等待它解开它的价值。然后返回this.http.post 的结果,即预期的Observable。为此,请在 try/catch 块内使用 await 关键字:

async deleteInvite(inviteId) 
    try 
        const headers = await this.getHttpHeader();
        return this.http.post(this.apiURL + "/deleteInvite", inviteId,  observe: "response", headers: headers );
    
    catch (err) 
        console.error(err);
    

然后在消费者端做await deleteInvite(inviteId)处理返回的Promise。

不过,混合 Observable 和 Promise 还是很复杂的。使用 Promises(或所有 Observables)做所有事情会更容易:“return await this.http.post().toPromise()”。

【讨论】:

我需要从这个方法deleteInvite()返回Observable。但是在您的实现中,由于async 而返回Promise this.http.post 将返回一个 observable。您必须使用 Observable.toPromise 将其转换为承诺 @Sampath:你是对的。使用async/await 会更清楚一点。但是我们不能直接解开deleteInvite返回的Promise,而是另一个await: `deleteInvite()` 在消费者端。与所有 rxjs 辅助脚手架相比,该代码更易于阅读。【参考方案2】:

FOR rxjs 版本:6.0.0 以上

import  from  from 'rxjs';

 deleteInvite(inviteId):Observable<HttpResponse<Object>> 
    return from(this.getHttpHeader()).pipe(
        switchMap(headers => 
            return this.http.post(this.apiURL + "/deleteInvite", inviteId,  observe: "response", headers: headers )
        ),
        catchError(err => 
            console.error(err);
        )
    );

对于旧版本的 rxjs:

使用 fromPromisethisGetHeaders() 转换为 Observable

import  fromPromise  from 'rxjs/observable/fromPromise';


deleteInvite(inviteId):Observable<HttpResponse<Object>> 
    return fromPromise(this.getHttpHeader()).pipe(
        switchMap(headers => 
            return this.http.post(this.apiURL + "/deleteInvite", inviteId,  observe: "response", headers: headers )
        ),
        catchError(err => 
            console.error(err);
        )
    );

【讨论】:

它给出了这个错误:[ts] The 'this' context of type 'void' is not assignable to method's 'this' of type 'Observable&lt;&gt;'. 可能与您的 rxjs 运算符有关。***.com/questions/47198706/… 您正在使用哪个版本? "rxjs": "5.5.2", import Observable from 'rxjs/Observable'; import fromPromise from 'rxjs/observable/fromPromise'; import switchMap from 'rxjs/operator/switchMap'; 有什么线索吗? 更改为import switchMap from 'rxjs/operators' 现在,这个错误:[ts] Argument of type ' observe: "response"; headers: void | HttpHeaders; ' is not assignable to parameter of type ' headers?: HttpHeaders | [header: string]: string | string[]; ; observe?: "body"; params?: Ht...'. Types of property 'headers' are incompatible. Type 'void | HttpHeaders' is not assignable to type 'HttpHeaders | [header: string]: string | string[]; '. Type 'void' is not assignable to type 'HttpHeaders | [header: string]: string | string[]; '.

以上是关于在 Promise 中返回 Observable的主要内容,如果未能解决你的问题,请参考以下文章

在 Observable 中调用 Promise

关于获取Promise返回值的问题!

在 Flow 中使用 Promise 作为返回类型

我如何最终在 Lambda 函数中返回 promise 的值?

使用 typescript 在 Redux thunk 中返回一个 Promise

vue返回二次promise