Angular JS Promise 所有顺序

Angular JS Promise all sequential

我正在尝试执行 3 个带有承诺的 Web 服务,我需要在所有这些服务都执行后,如果可能的话按顺序执行,我将 return 这 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);
});

谢谢。

您的实施存在一些问题。

  1. 首先,如果您使用 HttpClient,则不必 map 然后在响应中调用 json
  2. 您没有从 this.services.getServices(url)then 中 return。因此 Promise.all
  3. 没有回应

修复如下。


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

你的 console.log 中出现未定义的原因是这里的代码

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

由于没有返回任何内容(如有注明),推入 Promises 的 Promise 将解析为 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));

至于你问题的另一部分......你想这样做"sequentially"

如果你可以使用 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);
    }
}