简体   繁体   English

从Observable获取值 <value> 宾语

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

I am writing a service function where is it supposed to reply the latest price of a product. 我正在编写一个服务功能,该功能应在哪里答复产品的最新价格。 I connect to my server - using websocket and I get a DataStream using the Rxjs observable, now the function in the service layer is supposed to reply back only the value and not the Observable object. 我连接到服务器-使用websocket,并使用Rxjs observable获得了DataStream,现在服务层中的函数应该仅返回值,而不是Observable对象。

Sample code I am trying 我正在尝试的示例代码

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.
  }

but for obviously reason I am unable to return the number - since it is inside the subscribe callback where the context changes and the function is async 但由于明显的原因,我无法返回该数字-因为它位于订阅回调内部,上下文发生了变化并且该函数是异步的

How can I await for the reply from Observable and then return only the value received in the observable. 我如何等待Observable的答复,然后仅返回Observable中收到的值。

The only real way to do this is to return a promise. 做到这一点的唯一真实方法是兑现承诺。 Because the call is asynchronous you wont be able to return just the value. 由于该调用是异步的,因此您将无法仅返回该值。 Something like this would work: 这样的事情会起作用:

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

Then you can call it like this: 然后您可以这样称呼它:

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

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

I would suggest using toPromise like this: 我建议像这样使用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()
}

Note take(1) operator which will take first value and also unsubscribe the DataStream. 请注意take(1)运算符,该运算符将获取第一个值,同时也取消订阅DataStream。

Im not sure of the await feature of Angular but looking at the documentation it looks like it would be something like this: 我不确定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();
}

Then you can call it by using the await keyword: 然后,您可以使用await关键字来调用它:

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

Note that the function is prefixed with the "async" keyword, this is needed if the function has an "await" keyword within it. 请注意,该函数以“ async”关键字为前缀,如果函数中包含“ await”关键字,则需要此前缀。

The "async" keyword will mean that the console.log will not be hit until the promise from the "getRealTimePrice()" function is resolved (or rejected). “ async”关键字将意味着在“ getRealTimePrice()”函数的承诺得到解决(或拒绝)之前,不会击中console.log。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM