Угловой JS Promise все подряд - PullRequest
0 голосов
/ 12 октября 2018

Я пытаюсь выполнить 3 веб-сервиса с обещаниями, и мне нужно, чтобы после того, как все они будут выполнены, если возможно, последовательно, я верну информацию о 3 сервисах.У меня есть это.

это мой сервис

getServices(url: string): Promise < any > {
  return this.http.get(CoordinadoresService.BASEURL + url)
    .toPromise()
    .then(response => {
      return response.json();
    })
    .catch(err => err);
}

это мой компонент

getOffices() {
  this.oficinas["coordinadores"] = [];
  let data = this.util.getLocalStorage("coordinadores");
  let promises = [];
  if (data != undefined) {
    for (let i = 0; i < Object.keys(data.coordinadores).length; i++) {
      let url = `getOficinas/${data.coordinadores[Object.keys(data.coordinadores)[i]].ip}/${Object.keys(data.coordinadores)[i]}`;
      promises.push(this.services.getServices(url).then(response => {
          response["coordinador"] = response.coordinador;
          this.oficinas["coordinadores"].push(response)
        },
        err => err));
    }

    Promise.all(promises).then(data => {
      console.log('Both promises have resolved', data);
    });
  }
}

Но здесь он возвращает мне неопределенное.почему?

Promise.all(promises).then(data => {
  console.log('Both promises have resolved', data);
});

Спасибо.

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Причина, по которой вы получаете неопределенные значения в вашем console.log, заключается в следующем:

  promises.push(this.services.getServices(url)
 .then(response => {
      response["coordinador"] = response.coordinador;
      this.oficinas["coordinadores"].push(response);
      // nothing returned
  }, err => err));

Поскольку ничего не возвращено (где отмечено), обещание, переданное в Обещания, преобразуется в undefined* 1005.*

просто добавьте return response

примечание: response["coordinador"] = response.coordinador; избыточно, это все равно что сказать a = a - поэтому я не буду повторять его в коде ниже

также this.oficinas["coordinadores"]this.oficinas.coordinadores - поэтому будет использовать последний

  promises.push(this.services.getServices(url)
 .then(response => {
      this.oficinas.coordinadores.push(response);
      // something returned
      return response;
  }, err => err));

Что касается другой части вашего вопроса ... что вы хотите сделать это «последовательно»

Если вы можете использоватьasync / await - это очень легко изменить

async getOffices() { // add async keyword
    this.oficinas.coordinadores. = [];
    let data = this.util.getLocalStorage("coordinadores");
    let results = []; // no longer dealing directly with promises, so lets rename this
    if (data != undefined) {
        for (let i = 0; i < Object.keys(data.coordinadores).length; i++) {
            let url = `getOficinas/${data.coordinadores[Object.keys(data.coordinadores)[i]].ip}/${Object.keys(data.coordinadores)[i]}`;
            // await the promise
            let result = await this.services.getServices(url).then(response => {
                this.oficinas.coordinadores.push(response);
                return response;
            }, err => err);
            // push the result
            results.push(result);
        }
        // output the result
        console.log('Both promises have resolved', results);
    }
}

и - потому что

let url = `getOficinas/${data.coordinadores[Object.keys(data.coordinadores)[i]].ip}/${Object.keys(data.coordinadores)[i]}`;

выглядит просто беспорядочно, позвольте мне предложить альтернативу

async getOffices() {
    this.oficinas.coordinadores. = [];
    let data = this.util.getLocalStorage("coordinadores");
    let results = [];
    if (data != undefined) {
        for (let [key, {ip}] of Object.entries(data.coordinadores)) {
            const url = `getOficinas/${ip}/${key}`;
            let result = await this.services.getServices(url).then(response => {
                this.oficinas.coordinadores.push(response);
                return response;
            }, err => err);
            results.push(result);
        }
        console.log('Both promises have resolved', results);
    }
}
0 голосов
/ 12 октября 2018

Есть несколько проблем с вашей реализацией.

  1. Сначала, если вы используете HttpClient, вам не нужно будет map, а затем вызовите json в ответе.
  2. Вы не вернулись с then из this.services.getServices(url).Следовательно, нет ответа в Promise.all

Ниже приводится исправление.


import { HttpClient } from '@angular/common/http';
...
constructor(private http: HttpClient) {}
....
getServices(url: string): Promise < any > {
  return this.http.get(CoordinadoresService.BASEURL + url)
    .toPromise();
}

getOffices() {
  this.oficinas["coordinadores"] = [];
  let data = this.util.getLocalStorage("coordinadores");
  let promises = [];

  if (data) {

    for (let i = 0; i < Object.keys(data.coordinadores).length; i++) {
      let url = `getOficinas/${data.coordinadores[Object.keys(data.coordinadores)[i]].ip}/${Object.keys(data.coordinadores)[i]}`;
      promises.push(this.getDataFromAPI(url));
    }

    Promise.all(promises).then(data => {
      console.log('Both promises have resolved', data);
    });
  }
}

private getDataFromAPI(url) {
  return this.services.getServices(url)
    .then(
      response => {
        response["coordinador"] = response.coordinador;
        this.oficinas["coordinadores"].push(response)
        return response;
      },
      err => err
    );
}
...