Typescript 等待可观察到的分辨率

Typescript 等待可观察到的分辨率,typescript,http,async-await,rxjs,event-loop,Typescript,Http,Async Await,Rxjs,Event Loop,我已经在一个项目中工作了几个月了。它的范围是在同步环境下工作,不需要http请求和其他外部异步访问。现在我必须从http请求中获取数据。我有以下许多代码片段: get foo(){返回this.value;} 现在,使用http,我需要获取这个值,当我收到它时,只需将变量设置为响应 fetchValue(){this.http.get(addr.subscribe(resp=>this.value=resp);} get foo(){this.fetchData();返回this.value;

我已经在一个项目中工作了几个月了。它的范围是在同步环境下工作,不需要http请求和其他外部异步访问。现在我必须从http请求中获取数据。我有以下许多代码片段:

get foo(){返回this.value;}
现在,使用http,我需要获取这个值,当我收到它时,只需将变量设置为响应

fetchValue(){this.http.get(addr.subscribe(resp=>this.value=resp);}
get foo(){this.fetchData();返回this.value;}
这显然不起作用,因为
This.foo
将始终返回未定义,因为事件循环仅在所有这些逻辑之后触发,因此只有在函数解析后才设置值。我也不能在一段时间内循环,因为这将导致同步执行,永远不允许执行http请求

有没有办法在同步循环中强制停止,然后启动异步循环并等待其完成?或者至少在事件循环中等待一个函数完成

我不能重构代码,这不仅是因为它会导致代码的完全重新生成,并且花费的时间会增加一倍以上,而且还会破坏本项目所必需的向后兼容性。所以我需要foo在设置之后返回值;我无法在代码的任何其他部分向承诺添加订阅或解决方案来处理此问题

如果这是不可能的,为什么呢?我需要对阻碍使用此逻辑的语言范例进行清楚的解释。

无法“停止”事件循环,因为它基本上是javascript的主要机制。停止事件循环实际上意味着停止应用程序的执行:)

为了更好地理解事件循环,我绝对推荐您观看这部影片——这可能是对本主题的最好解释

现在,让我们修复您的代码。 使用“等待”异步操作完成是可能的,多亏了语法,它可以以非常漂亮的方式完成

首先,由于您使用的是rxjs,因此需要将http调用转换为承诺。这可以使用
.toPromise()
操作符完成

async fetchValue() {
  this.value = await this.http.get(addr).toPromise();
}
注意,我在函数名之前放了一个
async
关键字,这允许我们在函数中使用
wait
。wait期望promise是正确的,并将阻止它下面的代码运行,直到promise得到解决

您的第二个函数现在还需要具有async/await:

async getFoo() { 
  await this.fetchData();
  return this.value;
}
async function someMethod() {
  const foo = await instance.getFoo();
}
Tbh,我不知道你为什么需要它,因为第一个函数实际上做同样的工作,但好的,我只是想告诉你这个概念

现在,无论何时调用
instance.getFoo()
您都需要记住它是异步的,因此您应该在调用
instance.getFoo()
的函数中使用
async/wait
,或者使用
。然后使用
来获取值

使用异步/等待:

async getFoo() { 
  await this.fetchData();
  return this.value;
}
async function someMethod() {
  const foo = await instance.getFoo();
}
使用
。然后()


同样,我建议您花一些时间观看上面的视频,阅读承诺和异步/等待的文档。

很抱歉回复太晚。不幸的是,我无法使用此解决方案。声明foo的公共API正在许多项目中使用,它应该是一个同步函数。如果我将其设置为异步函数,那么API的所有用户都需要将其客户端设置为异步,而这是不可能的。我需要一种方法来等待http客户端响应,然后允许对api的调用进行解析。或者诸如此类的东西。@MuriloMaestro,如果你看了视频,你应该明白以这种方式实现是不可能的。您可以为
foo
属性使用一个同步getter,但是如果以前设置过,它将返回一个值,或者返回
未定义的