Как решить «ЗНАЧЕНИЕ НИЖЕ БЫЛО ОЦЕНЕНО ТОЛЬКО СЕЙЧАС» в angular

#angular

#angular

Вопрос:

Пожалуйста, помогите, я просматриваю subscribe, а затем сохраняю данные в массиве, но в результате отображается пустой массив

ниже приведено изображение

вывод на консоль

 let pid = this._commonFn.getDataFromLocalStorage("pid");
let filteredData: any = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
Promise.all(filteredData.map((d) => {
    this._productService.getRdaData(pid, d.id).subscribe((resp: any) => {
      if (resp.success amp;amp; "data" in resp) {
        resp.data.forEach((element) => {
          allNutrientData.push(element);
        });
      }
    });
  })
).then((result) => console.log(allNutrientData));
  

или

 let filteredData: any = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
filteredData.map((d) => {
  this._productService.getRdaData(pid, d.id).subscribe((resp: any) => {
    if (resp.success amp;amp; "data" in resp) {
      resp.data.forEach((element) => {
        allNutrientData.push(element);
      });
    }
  });
});
  

я получаю «ЗНАЧЕНИЕ НИЖЕ БЫЛО ОЦЕНЕНО ТОЛЬКО СЕЙЧАС»

Комментарии:

1. Это сообщение связано с тем, что console.log происходит до того, как массив будет изменен с обратного вызова в подписке на вызов api, но когда вы разворачиваете массив в консоли, он будет печатать то, что содержит массив «сейчас», а не когда он был зарегистрирован изначально.

2. Я знаю это .. но как я могу это решить…

3. this._productService.getRdaData(pid, d.id) возвращает наблюдаемое, а не обещание, поэтому вы можете использовать RxJS для сбора данных вместо Promise.all .

4. Rxjs, каким оператором вы могли бы меня направить

Ответ №1:

Первое, что следует отметить, это то, что this._productService.getRdaData(pid, d.id) возвращает наблюдаемый RxJS, а не обещание. Это означает, что мы можем использовать RxJS для обработки этих результатов вместо того, чтобы делать это через Promise.all . Это немного сложно, если вы привыкли решать эти проблемы с помощью promises. Использование наблюдаемых для решения этой проблемы читается совсем по-другому.

 // first, convert the array into a stream of items
from(filteredData).pipe(
  // map items to the request observable, maintaining order (like Promise.all)
  concatMap(d => (
    this._productService.getRdaData(pid, d.id)
  )),
  // map responses to the data
  map(resp => {
    if (resp.success amp;amp; "data" in resp) {
      return resp.data;
    }
  }),
  // filter out empty responses
  filter(data => data !== undefined),
  // collect the data as an array ([[data1, data2], [data3, data4]...]
  toArray()
  // use concat to flatten the array
  // in this callback is where you can operate on the final data
).subscribe(data => console.log([].concat(...data)))
  

Комментарии:

1. Спасибо… приятель …. это сработало, и теперь проблема решена