Как сделать синхронный вызов в angular 11

Итак, я пытался решить эту проблему, используя async/await. Но я не могу этого сделать, может быть из-за отсутствия знаний в angular. Мне нужно получить доступ к значениям ответа, назначенным в async fetchData() в компоненте

Значения по умолчанию, назначенные сотруднику, — ВСЕ.

асинхронная функция в компоненте:

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

вызов функции: -

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);          }
  }

к новым значениям сотрудников я применяю фильтры, но не могу получить значения из асинхронного вызова.

Консольный вывод: -

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)

поэтому после этого прогона я хочу, чтобы сотрудники оценивали, как показано в ответе.

Пожалуйста, предложите.


person SwapnilM    schedule 12.03.2021    source источник
comment
вопрос должен быть: почему мне нужно сделать синхронный вызов? Это плохой дизайн. Вы должны использовать операторы Observables -not convert to promise- и rxjs, если вы хотите преобразовать ответ и в подписке сделать что-то с ответом   -  person Eliseo    schedule 12.03.2021
comment
@Eliseo: - Итак, у меня есть ситуация, у меня есть 5 выпадающих списков, теперь при изменении события одного из выпадающих значений других четырех меняется, поэтому теперь я хочу, чтобы выпадали значения других четырех, и мне нужно применить фильтры к этому, чтобы показать данные на сетке данных. Итак, я пытаюсь получить записи из вызова API и получить требуемый идентификатор из ответа, который поможет отфильтровать данные. ЕСЛИ у вас есть лучшее предложение, пожалуйста, помогите.   -  person SwapnilM    schedule 12.03.2021


Ответы (3)


Это ожидаемое поведение. В вашем коде нет ничего плохого. Ваше понимание того, как это работает, неверно.

Ваша функция fetchData является асинхронной, это означает, что она будет выполняться асинхронно. Внутри fetchData вы можете выполнять несколько http-запросов и ждать ответа на каждый http-запрос, прежде чем выполнять следующий http-запрос.

Итак, вам нужно переместить код, который вы хотите выполнить после http-запроса, внутрь fetchData.

person Agam    schedule 12.03.2021

Я не вижу здесь необходимости преобразовывать наблюдаемое в обещание. Вы можете вернуть простой Observable и подписаться на него там, где нужны данные. И нет, нет возможности преобразовать асинхронный вызов в синхронный.

Примечание: любые операторы, напрямую зависящие от ответа на асинхронный запрос, должны находиться внутри подписки. Другими словами, подпишитесь на наблюдаемое, где требуется его ответ.

Пожалуйста, просмотрите этот ответ и вопрос, чтобы получить общее представление об асинхронных запросах.

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
    }
  });
}
person Michael D    schedule 12.03.2021

Весь смысл использования наблюдаемого состоит в том, чтобы получить поток данных с одной стороны с другой стороны, в вашем случае со стороны сервера на клиент. toPromise() не рекомендуется использовать, поскольку вы извлекаете только первые данные в потоке, а не после этого. Поэтому я рекомендую оставить простое наблюдаемым. Также похоже, что у вас есть проблема с передачей значений в коде. В качестве примера можно использовать следующий фрагмент кода.

Observable извлекает весь массив, как я испытал, по крайней мере, так это выглядит, когда вы кодируете, то есть данные, которые вы видите во фрагменте кода, фактически извлекаются сервером. Есть массив, и его элементами являются объекты. вы можете присвоить его переменной, а затем использовать for() с of для чтения их значений. Лучше использовать предложение return с HTTPClient.Get(), чтобы вернуть ответ, а затем прочитать этот ответ через наблюдаемое, например HttpClient.Get().Subscribe(response =› { console.log(response);})'

  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" }
    ];
  }
person Don Dilanga    schedule 12.03.2021