Я пытаюсь выполнить 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);
});
Спасибо.
Есть несколько проблем с вашей реализацией.
HttpClient
вам не придется map
а затем вызывать json
в ответ.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
);
}
Причина, по которой вы получаете 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);
}
}
HttpClient
илиHttp
?Promise
, вызвавthen
на него. Таким образом, ваш массив Promises не будет содержатьPromise
как таковое.