Angular/RxJS: 同步可观察对象

25

我有一个服务,其中有一个名为foo的方法。在该方法内部,我订阅了一个可观察对象(http-client)。

foo () : boolean
{
  let ret : false;

  this.http.get ("/blabla").subscribe (
  (resp) =>
  {
    ret = true;
  }

  return ret;
);

我希望从foo函数中返回一个布尔值,其取决于get方法的结果。但是由于http.get是异步的,所以这并不起作用 - return在http.get完成之前就被调用了。

我该如何使它同步?

编辑

在这里,返回observable而不是布尔值不是一个选项。因为我在foo中处理get的响应(此处未显示),但我还需要根据其返回情况在foo之外进行操作。

EDIT2

我使用pipe和tap扩展了我的示例。现在我将http.get可观察对象返回给服务之外,并通过tap处理http.get结果。

foo () : Observable <any>
{
  return this.http.get ("/blabla").pipe (tap (x => handlehere ()));
}

在我看来,它只有一个缺点,就是解析get-result的复杂性要在 foo 内部和外部同时处理。我更希望在 foo 外部使用一个简单的布尔值。


1
可能是如何从异步调用中返回响应?的重复问题。 - Igor
2
“我该如何将它变成同步的?” <= 不需要,你可以返回一个Observable或者Promise。 “在这里返回Observable而不是Boolean不是一个选项” <= 为什么不呢? - Igor
2
那么你没有选择,因为同步代码可以在一个操作中变成异步代码,但是异步代码永远无法再次变成同步代码。 - smnbbrv
但是我还需要根据foo的返回值来采取行动。然后,将对调用的操作也异步发生。一旦您了解了异步JavaScript(TypeScript)代码/交互使用的模式,编写应用程序就会变得更加容易。通常应用程序中存在大量的异步交互,因为它们与外部资源(用户输入、数据库、网络流等)进行交互。这将使您成为更好的程序员。 - Igor
返回一个Observable也是可能的,但它必须与http.get相关联。我不知道如何做到这一点。 - chris01
显示剩余2条评论
1个回答

27

这种方法只能异步运行,因此选择不多。可以返回Observable并订阅,也可以返回Promise。也许返回Promise更适合你的需求,以便更好地理解。

在你的服务中:foo方法:

async foo() {
   const result = await this.http.get("/blabla").toPromise();

   // do what you want with result 

   return result;
}

如何称呼它:

this.myService.foo().then( (result) => {
   // Do what you want with the result
});

2
toPromise()已被弃用,并将在v8中删除。有人找到了类似的解决方法吗? - Jake_3H
4
你可以使用firstValueFrom(observable)代替toPromise()。 - Santhosh Nagaraj
1
这个答案在Angular中不是同步的。firstValueFrom(observable)也不是同步的,因为你必须等待两个调用,这意味着在等待结果时其他资源可以执行操作。 - gangfish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接