【问题标题】:Wait for response from HttpClient get - synchronous call等待来自 HttpClient 的响应 get - 同步调用
【发布时间】:2021-09-20 23:28:06
【问题描述】:

我想知道如何等待来自调用后端的 HttpClient 操作的响应,我需要等到后端返回给出响应(同步调用),经典方法是订阅 Observable 响应:

//My component
...
console.log("before");
this.myService.getSomeThingFromBackend('param_value').subscribe(response => {
     console.log("do my stuff");
}
console.log("after");

//My Service
...
getSomeThingFromBackend(param: string): Observable<any>{
        return this.httpClient.get(this.host + this.url+ "/" + param);
}

这表明:

before

after

do my stuff

我想要这个结果:

before

do my stuff

after

【问题讨论】:

  • 只需将console.log("after") 放在订阅中,因为它是一个异步过程。

标签: javascript angular typescript angular-httpclient


【解决方案1】:

Angular 的 this.http.get 返回一个 RxJS Observable。然后调用 this.http.get(...).subscribe(...) 返回 RxJS Subscription 对象。所以它们都没有返回 Promise,所以你不能将它们与 await 一起使用。

如果您希望能够将 await 与 Observables 一起使用,您必须使用 toPromise() 而不是 subscribe(),它返回一个由该 Observable 发出的第一个值解析的 Promise(它在内部调用 subscribe给你,并用 Promise 对象包装它)。

await this.http.get(...).toPromise(value => {
  ...
});

【讨论】:

  • 我看到很多人建议通过将可观察的问题转换为承诺来解决这些问题。不!这只是意味着 observables 的使用不正确。使用 Promise 意味着你会失去 RxJS 的强大功能。
  • @KurtHamilton 我需要同步进行通话,无论如何感谢您的澄清,这是 100% 正确
  • @Sanjay Lohar 我只想补充一点,应该使用 then() 结束 catch() 方法来处理承诺
  • 是的,请给出正确的语法,以便其他人可以使用标准方法。
  • @JacopoSciampi 问题已编辑,我认为已经很清楚了
【解决方案2】:

听起来很明显的风险...如果您想一个接一个地执行一个动作,那么移动位于错误位置的动作。

//My component
...
console.log("before");
this.myService.getSomeThingFromBackend('param_value').subscribe(response => {
  console.log("do my stuff");
  console.log("after");
}

//My Service
...
getSomeThingFromBackend(param: string): Observable<any> {
  return this.httpClient.get(this.host + this.url+ "/" + param);
}

你所做的一切都是正确的。您正在从服务返回可观察对象,在组件中订阅它,并在订阅中运行操作。

【讨论】:

    【解决方案3】:

    这个过程是异步工作的,所以你不能让它等待其他东西,直到它们在响应范围内。您可以在同一范围内编写这些调用,也可以创建一个函数并从内部调用它。

    //My component
    
    ...
    console.log("before");
    this.myService.getSomeThingFromBackend('param_value').subscribe(response => {
         console.log("do my stuff");
         doSomeStuff();
    }
    
    doSomeStuff(){
        console.log("after");
    }
    
    //My Service
    ...
    getSomeThingFromBackend(param: string): Observable<any>{
            return this.httpClient.get(this.host + this.url+ "/" + param);
    }
    

    【讨论】:

      【解决方案4】:

      您可能不想在这种情况下使用 HttpClient。 如下使用同步 http请求

      var request = new XMLHttpRequest();
      request.open('GET', "https://domain/api", false);  
      request.send(null);
      const response = JSON.parse(request.responseText); 
      

      使用HttpClient 无法利用 DI,因此应在需要时绝对使用。

      【讨论】:

        猜你喜欢
        • 2016-02-14
        • 1970-01-01
        • 2021-11-24
        • 1970-01-01
        • 2019-06-27
        • 1970-01-01
        • 1970-01-01
        • 2011-09-03
        • 1970-01-01
        相关资源
        最近更新 更多