RX JS Использование ForkJoin с объектами - PullRequest
2 голосов
/ 07 мая 2020

Я пытаюсь использовать forkJoin для запуска массива объектов с ключом и значением, которое является наблюдаемым. Мне нужно сделать это там, где массив объектов приведет к тому, что ключ будет одинаковым, а значение будет результатом наблюдаемого вызова api. Этот объект может иметь любое количество пар ключ-значение. И мне нужно подождать, пока все они будут выполнены, прежде чем я смогу продолжить. Я пробовал использовать ForkJoin, но, похоже, он принимает только массив наблюдаемых и никаких ключей. Эти ключи важны, чтобы я знал, какой URL-адрес связан с каким ключом, чтобы я мог сохранить их в нужном месте. Исходное соединение fork вернет массив объектов, которые представляют результат вызовов api, но я понятия не имею, какой из них принадлежит какому ключу.

Есть какие-нибудь мысли по этому поводу?

Ответы [ 4 ]

5 голосов
/ 08 мая 2020

Из Rx JS v6.5 + , вы можете использовать словарь (пары ключ-значение) в качестве источников.

Пример и Stackblitz получено из Обучение Rx JS:

forkJoin(
  // as of RxJS 6.5+ we can use a dictionary of sources
  {
    google: ajax.getJSON('https://api.github.com/users/google'),
    microsoft: ajax.getJSON('https://api.github.com/users/microsoft'),
    users: ajax.getJSON('https://api.github.com/users')
  }
)
.subscribe(
  response => { 
    console.log(response['google']); 
    console.log(response['microsoft']); 
    console.log(response['users']); 
  }
);
0 голосов
/ 08 мая 2020

Javascript Объекты не упорядочены, поэтому, если вы получите обратно только массив наблюдаемых, вы не можете быть уверены, что он принадлежит одному конкретному ключу.

Давайте попробуем таким образом, получите key, value сначала пары, как массив. Мы будем использовать ключи даже в качестве Observables и применять forkJoin как к keys, так и к фактическим запросам, чтобы, когда они приходят, они объединяются. Наконец, мы можем применить forkJoin ко всем forkJoins и преобразовать результаты обратно в объект с помощью карты.

    const myObject = {
        headerLogo: this.http.post(url, image),
        loginBackground: this.http.post(url2, image)
    }

    const keyValuesAsObservables = Object.entries(myObject).map(([k, v]) => {
        return forkJoin(of(k), v);
    });

    forkJoin(...keyValuesAsObservables).pipe(map(res) => {
        return Object.fromEntries(res);
    });
0 голосов
/ 08 мая 2020

Поскольку в вашем примере показан не массив объектов, а просто объект, я предполагаю, что это то, что вы используете. Вы можете получить доступ к свойствам полученного объекта (обратите внимание, что я использую деструктор объекта в подписке, потому что он выглядит красиво и чисто):

forkJoin({
  headerLogo: this.http.post(url, image),
  loginBackground: this.http.post(url2, image)
})
.subscribe( ({headerLogo, loginBackgroud}) => {
  // .....
})
0 голосов
/ 08 мая 2020

forkJoin вернет результаты в том же порядке. Это означает:

forkJoin([
  this.http.post(url, image),
  this.http.post(url2, image),
]).subscribe(([resultOfApiCall, resultOfApiCall2]) => {
  // save result of API1 with resultOfApiCall
  // save result of API2 with resultOfApiCall2
})
...