从Observable获取值 宾语

问题描述 投票:0回答:4

我正在写一个服务功能,它应该回复产品的最新价格。我连接到我的服务器 - 使用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中收到的值。

javascript rxjs observable
4个回答
0
投票

唯一真正的方法是返回一个承诺。因为调用是异步的,所以你不能只返回值。像这样的东西会起作用:

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);
});

0
投票

理想情况下,您应该从getRealTimePrice方法中的getDataStream()调用返回Observable,并在预期数据的位置执行预订。


0
投票

我建议像这样使用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。


0
投票

我不确定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()”函数的promise被解析(或拒绝)之前,不会命中console.log。

© www.soinside.com 2019 - 2024. All rights reserved.