简体   繁体   English

如何在 angular 11 中进行同步调用

[英]How to make a synchronous call in angular 11

So, I was trying to get the solution of this problem by using async/await.所以,我试图通过使用 async/await 来解决这个问题。 But, I am unable to do so, May be because of the lack of knowledge in angular.但是,我不能这样做,可能是因为angular缺乏知识。 I have to access response values assigned in async fetchData() in component我必须访问组件中异步 fetchData()中分配的响应值

The default values assign to employee is ALL分配给员工的默认值是 ALL

async function in component:组件中的异步 function:

async fetchData(empId:string, empUrl:string) {
    this.message = "Fetching..";    
    this.resp = await this.http
      .get<any>(empUrl+empId)     
      .toPromise();
    this.message = "Fetched";
  }

function call:- function 致电:-

getEmployeeById(empId:string, empUrl:string){
    console.log("Get employee by empId....");    
    console.log("Before calling Employee API Call:");
    for (var obj of this.empResp) {
        console.log("empId   : " +obj.empId); 
        console.log("empName : " +obj.empName);  
    }

    console.log("************calling asynch call");
    this.fetchData(empId, empUrl);
    console.log("************back");

    console.log("After calling Employee API Call:");
    for (var obj of this.empResp) {
        console.log("empId   : " +obj.empId); 
        console.log("empName : " +obj.empName);          }
  }

on new employee values I have apply filters but not able to get the values out side async call.在新员工值上,我应用了过滤器,但无法从异步调用中获取值。

Console OutPut:-控制台 OutPut:-

app.component.ts:65 Get employee by empId....
app.component.ts:66 Before calling employee API Call:
app.component.ts:68 empId   : ALL
app.component.ts:70 empName : ALL
app.component.ts:72 ************calling asynch call
app.component.ts:74 ************back
app.component.ts:76 After calling employee Archive API Call:
app.component.ts:78 empId   : ALL
app.component.ts:80 empName : ALL

app.component.ts:61 (3) [{…}, {…}, {…}]0: {empId: "123", empName: "XYZ"}1: {empId: "324", empName: "ABC"}length: 2__proto__: Array(0)

so after this run I want employees value as shown in response.所以在这次运行之后,我希望员工的价值如回应所示。

Please suggest.请建议。

This is the expected behavior.这是预期的行为。 There is nothing wrong in your code.您的代码没有任何问题。 Your understanding on how it works is not correct.您对其工作原理的理解是不正确的。

Your function fetchData is "async", it means it will be executed asynchronously.您的 function fetchData 是“异步”的,这意味着它将异步执行。 Inside fetchData you can execute multiple http requests and await for the response of each http request before you execute the next http request.在 fetchData 中,您可以执行多个 http 请求并等待每个 http 请求的响应,然后再执行下一个 http 请求。

So, you need to move your code that you want to be executed after http request, inside fetchData因此,您需要在 http 请求之后将要执行的代码移动到 fetchData

I don't see the need here to convert the observable to promise.我认为这里不需要将 observable 转换为 promise。 You could return the plain Observable and subscribe to it where the data is needed.您可以返回普通的 Observable 并在需要数据的地方订阅它。 And no, there is no way to convert an asynchronous call to a synchronous one.不,没有办法将异步调用转换为同步调用。

Note: any statements that directly depend on the response from the async request must be inside the subscription.注意:任何直接依赖于异步请求响应的语句都必须在订阅中。 In other words, subscribe to the observable where it's response is required.换句话说,订阅需要响应的可观察对象。

Please go through this answer and it's question to get a general idea of async requests.请 go 通过这个答案,这是了解异步请求的一般概念的问题。

import { finalize } from 'rxjs/operators';

fetchData(empId:string, empUrl:string) {
  this.message = "Fetching..";    
  this.http.get<any>(empUrl+empId).pipe(
    finalize(() => this.message = "Fetched"   // <-- triggered when the request is complete
  );
}

getEmployeeById(empId:string, empUrl:string){
  console.log("Get employee by empId....");    
  console.log("Before calling Employee API Call:");
  for (var obj of this.empResp) {
      console.log("empId   : " +obj.empId); 
      console.log("empName : " +obj.empName);  
  }

  console.log("************calling async call");
  this.fetchData(empId, empUrl).subscribe({
    next: (res: any) => {
      this.empResp = res;       // <-- assign result here
      console.log("************back");
      console.log("After calling Employee API Call:");
      for (var obj of this.empResp) {
        console.log("empId   : " +obj.empId); 
        console.log("empName : " +obj.empName);          
      }
    },
    error: (error: any) => {
      // handle error
    }
  });
}

The whole point of using observable is to fetch a stream of data to one side from another side, in your case from server side to client.使用 observable 的全部意义在于从服务器端到客户端从另一端获取数据的 stream 到另一端。 toPromise() is not recommended to use as you only fetch the first data in the stream, no more after that.不建议使用 toPromise() ,因为您只获取 stream 中的第一个数据,之后不再使用。 So I recommend to keep the simple observable.所以我建议保持简单的可观察性。 Also it appears as you have a problem in passing values in the code.此外,您在代码中传递值时出现问题。 You can use the following code snippet as an example.您可以使用以下代码片段作为示例。

Observable fetches the whole array as I have experienced, at least that's how it looks like when you code, meaning the data you see in the code snippet is actually fetched by the server.正如我所经历的那样,Observable 获取整个数组,至少在您编码时是这样的,这意味着您在代码片段中看到的数据实际上是由服务器获取的。 There is an array, and its elements are objects.有一个数组,它的元素是对象。 you can assign it to a variable, and then use for() with of to read their values.您可以将它分配给一个变量,然后使用 for() 和 of 来读取它们的值。 It's better you use return clause with HTTPClient.Get() to return the response, then read that response via an observable like HttpClient.Get().Subscribe(response => { console.log(response);})'最好使用带有 HTTPClient.Get() 的 return 子句来返回响应,然后通过像 HttpClient.Get().Subscribe(response => { console.log(response);})' 这样的 observable 读取该响应

  public getEmployeeById() {
    let objArray = this.fetchData();
    for (let obj of objArray) {
      console.log("empId   : " + obj.empId);
      console.log("empName : " + obj.empName);
    }
  }

  fetchData() {
    return [
      { empId: 1, empName: "Don" },
      { empId: 2, empName: "Don2" },
      { empId: 3, empName: "Don3" }
    ];
  }

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

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