Параллельные http-запросы через forkJoin и идентификацию ответов - PullRequest
2 голосов
/ 15 января 2020

Я бы хотел сделать параллельные независимые вызовы к конечной точке.

Сначала я создаю свои вызовы, затем я вызываю forkJoin.

getAllDirections(data: Object, date: string) {
  let urls = [];
  for (let elm in data) {
    let url = `http:XXXXX?date=${date}&directions=${data[elm].All.join()}`;
    urls.push(this.http.get<ISchedules>(url));
  }
  return forkJoin(urls).pipe(
    map(dirData => {
      let dataSorted = dirData.map(elm => _.groupBy(elm.data, 'direction'));
      return dataSorted;
    })
  );
}

, параметры данных являются объектами параметров что я передаю URl

data = {
    b1: [params1],
    b2: [params2],
    b3: [params3]
}

То, что я в результате смогу построить этот объект

dataRes = {
    b1: [resDataofParams1],
    b2: [resDataofParams2],
    b3: [resDataofParams3]
}

Когда я получу ответ массива, я должен воздействовать на каждый элемент массива, соответствующий b{n}, Как я могу получить ответы в том же порядке, что и в forkJoin? Или есть способ передать параметр в this.http.get<ISchedules>(url) и получить его, когда я получу ответ данных?

Ответы [ 2 ]

1 голос
/ 15 января 2020

Начиная с Rx JS 6.5, вы можете передать словарь Observables в forkJoin, чтобы получить Объект с последним ответом от каждого Observable.

const http = (url: string) => of("response for " + url);
const data = {
  b1: ["b1-1", "b1-2"],
  b2: ["b2-1", "b2-2"],
  b3: ["b3-1", "b3-2"]
};
const date = '15.01.2020';

// map data to dictionary of http requests
const httpRequests = Object.keys(data).reduce((p, c) => {
  const url = `http:XXXXX?date=${date}&directions=${data[c].join(',')}`;
  return { ...p, [c]: http(url) };
}, {});

forkJoin(httpRequests).subscribe(console.log);

// output
{ 
  b1: "response for http:XXXXX?date=15.01.2020&directions=b1-1,b1-2", 
  b2: "response for http:XXXXX?date=15.01.2020&directions=b2-1,b2-2", 
  b3: "response for http:XXXXX?date=15.01.2020&directions=b3-1,b3-2"
}

https://stackblitz.com/edit/rxjs-qecpud

1 голос
/ 15 января 2020

На мой взгляд, лучше использовать уже созданный метод forkJoin () из библиотеки RXJS. В RX JS 6.5 вам нужно передать массив наблюдаемых :

const combined = Observable.forkJoin(
  [(this.http.get('https://foourl1').map((res: Response) => res.json()),
  of(this.http.get('https://foourl1').map((res: Response) => res.json())]
)

combined.subscribe(latestValues => {
    const [ data_changes , data_all ] = latestValues;
    console.log( "data_changes" , data_changes);
    console.log( "data_all" , data_all);
});

forkJoin вернет данные, когда все вызовы завершатся и вернет результат .

Другой пример:

const request1 = this.http.get('https://restcountries.eu/rest/v1/name/india');
const request2 = this.http.get('https://restcountries.eu/rest/v1/name/us');
const request3 = this.http.get('https://restcountries.eu/rest/v1/name/ame');
const request4 = this.http.get('https://restcountries.eu/rest/v1/name/ja');

const requestArray = [];
requestArray.push(request1);
requestArray.push(request2);
requestArray.push(request3);
requestArray.push(request4);

forkJoin(requestArray).subscribe(results => {
  console.log(results);
  this.response = results;
});

Все результаты упорядочены соответственно помещенным элементам в requestArray. Это можно увидеть в примере со стеком .

...