簡體   English   中英

從Observable獲取值 <value> 賓語

[英]get a value from a Observable<value> object

我正在編寫一個服務功能,該功能應在哪里答復產品的最新價格。 我連接到服務器-使用websocket,並使用Rxjs observable獲得了DataStream,現在服務層中的函數應該僅返回值,而不是Observable對象。

我正在嘗試的示例代碼

public getRealTimePrice(id: string): number {

 let ws = new $WebSocket('/price?Id=' + id + '&connectionId=' + this.randomUUID());
    this.priceWebsocket = ws;

    this.priceWebsocket.getDataStream()
      .map(msg => JSON.parse(msg.data).price)
      .subscribe(responseNumber => {
        return responseNumber // by the time execution reaches here the context is changed.
      });
    // I am not returning anything on the function level - which results in a compilation error as per typescript.
  }

但由於明顯的原因,我無法返回該數字-因為它位於訂閱回調內部,上下文發生了變化並且該函數是異步的

我如何等待Observable的答復,然后僅返回Observable中收到的值。

做到這一點的唯一真實方法是兌現承諾。 由於該調用是異步的,因此您將無法僅返回該值。 這樣的事情會起作用:

public getRealTimePrice(id: string): Promise<number> {
    return new Promise((resolve, reject) => {
        let ws = new $WebSocket('/price?Id=' + id + '&connectionId=' + this.randomUUID());
        this.priceWebsocket = ws;

        this.priceWebsocket.getDataStream()
        .map(msg => JSON.parse(msg.data).price)
        .subscribe(responseNumber => {
            resolve(responseNumber);
        });
    });
}

然后您可以這樣稱呼它:

getRealTimePrice().then((data:number) = {
    console.log(data);
});

理想情況下,您應該從getRealTimePrice方法中對getDataStream()的調用返回Observable,並在需要數據的位置進行預訂。

我建議像這樣使用toPromise

public getRealTimePrice(id: string): Promise<number> {
    let ws = new $WebSocket('/price?Id=' + id + '&connectionId=' + this.randomUUID());
    this.priceWebsocket = ws;

    return this.priceWebsocket.getDataStream()
        .map(msg => JSON.parse(msg.data).price)
        .take(1)
        .toPromise()
}

請注意take(1)運算符,該運算符將獲取第一個值,同時也取消訂閱DataStream。

我不確定Angular的等待功能,但是看一下文檔,看起來像這樣:

public getRealTimePrice(id: string): Promise<number> {

    let ws = new $WebSocket('/price?Id=' + id + '&connectionId=' + this.randomUUID());
    this.priceWebsocket = ws;

    this.priceWebsocket.getDataStream()
      .map(msg => JSON.parse(msg.data).price)
      .subscribe(responseNumber => {
        return responseNumber
      })
      .take(1)
      .toPromise();
}

然后,您可以使用await關鍵字來調用它:

async getAsyncValue(id: string) {
    const value = <number>await this.getRealTimePrice(id);
    console.log(`number: ${value}`);
}

請注意,該函數以“ async”關鍵字為前綴,如果函數中包含“ await”關鍵字,則需要此前綴。

“ async”關鍵字將意味着在“ getRealTimePrice()”函數的承諾得到解決(或拒絕)之前,不會擊中console.log。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM