我正在编写一个服务功能,该功能应该在其中答复产品的最新价格。我连接到服务器-使用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中收到的值。
答案 0 :(得分: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);
});
答案 1 :(得分:0)
理想情况下,应该从getRealTimePrice方法中的getDataStream()调用返回Observable,并在需要数据的位置进行预订。
答案 2 :(得分: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。
答案 3 :(得分: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()”函数的承诺得到解决(或拒绝)之前,不会击中console.log。