繁体   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