Как перебрать массив значений и вызвать сервис, который возвращает обещание, и ждать каждого результата в Angular 6 - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть проект Angular 6, где я получаю массив строк, и мне нужно вызвать бэкэнд-сервис с каждым элементом в массиве.

Код компонента (упрощенный) выглядит следующим образом:

items: any[] = ['one','two','three']

for (let item of this.items) {
    this.dataSvc.searchItems(item)
    .subscribe(
        data => {
            console.log(item, data);
        })
}

И код службы Angular, подобный следующему:

public searchItems(item: string): Observable<any> {
        let params = new HttpParams();

        params = params.append('item', item);

        return = this.httpClient.get(SERVER_API, { params: params })
}

Это прекрасно работает с одним элементом в массиве, однако, когда массив масштабируется, служба начинает выдавать ошибки тайм-аута и возвращать некоторые,но не все результаты.

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

Вот как я справился с цепочкой обещанийв другом месте с оберткой Promise в компоненте:

fetchService(item): Promise<any> {
    return this.dataSvc.searchItems(item)
        .toPromise();
}

this.fetchService('one')
    .then(data => {
        console.log("one", data);
        return this.fetchRegCodeLit('two')
    }).then(data => {
        console.log("two", data);
        return this.fetchRegCodeLit('three')
    }).then(data => {
        console.log("three", data);
    })

Массив items является динамическим, он может содержать 10 или 100 элементов, и мне нужно иметь возможность передавать каждый элемент втот же сервис и гарантирую, что я получил ответ и обработал его перед повторным вызовом сервиса, но я не могу понять, как это сделать.

Я смотрю на async / await, и ядумаю, в этом и заключается решение, но любая попытка перестановки кода, которую я пробовал, приводит к ошибкам компиляции, поэтому я явно что-то упускаю.

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Использование toPromise () может быть хорошей вещью.Вы можете запустить все параллельно и дождаться результата с помощью Promise.all () .

items: any[] = ['one','two','three']

//list of http promise
const itemsSearchPromise = [];

for (let item of this.items) {
   itemsSearchPromise.push(this.dataSvc.searchItems(item).toPromise());
}

Promise.all(itemsSearchPromise).then( (datas) => {
  //datas is an array of every result in the order of the "itemsSearchPromise"
}
0 голосов
/ 18 сентября 2018

Я думаю, что async / await - тоже ответ.Это должно быть просто как:

public async searchItems(item: string): Observable<any> {
    let params = new HttpParams();

    params = params.append('item', item);

    request = await this.httpClient.get(SERVER_API, { params: params });

    return request;
}

Ваш fetchService выглядит хорошо для меня.Вот сайт, который может пролить свет на обещания.

https://medium.com/@balramchavan/using-async-await-feature-in-angular-587dd56fdc77

...