Угловой JS Promise все подряд

1

Я пытаюсь выполнить 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);
});

Спасибо.

  • 0
    Используя HttpClient или Http ?
  • 0
    Вы разворачивание Promise , вызвав then на него. Таким образом, ваш массив Promises не будет содержать Promise как таковое.
Показать ещё 9 комментариев
Теги:
angular
promise
angular2-services

2 ответа

2
Лучший ответ

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

  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
    );
}
  • 0
    Спасибо @SiddAjmera
  • 0
    Рад, что это помогло. :)
0

Причина, по которой вы получаете undefined в своем console.log, - вот этот код здесь

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

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

просто добавьте 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);
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню