簡體   English   中英

Angular rxjs 異步數組未定義

[英]Angular rxjs async array undefined

有一個newData數組和 rxjs forkJoin運算符有兩種方法。 我試圖在getNewData()中填充數組以便在 forkJoin 訂閱中使用它,但它仍然未定義。 等待在getNewData()中填充 newData 數組以便在 forkJoin 訂閱中使用它的合適方法是哪種?

    newData = [];
    
    forkJoin(
      this.method1();
      this.method2()
    ).subscribe({ data1, data2 }) => {
       const filteredData = data1.filter(item => item.id === model.id);
       this.getNewData(filteredData);

       console.log(this.newData) => undefined

       // wait for this.newData?
    }

    // Observable
    getNewData(filteredData) {
      return this.API('GET', `data/${filteredData.id}`).pipe(map((resp: any) => {
          this.newData = resp;
        }));
    }

只需將方法getNewData作為第三個參數添加到forkjoin ,您的子程序中就會有 newData

    forkJoin(
      this.method1();
      this.method2(), 
      this.getNewData() 
    ).subscribe([ data1, data2 , newData]) => {
       const filteredData = data1.filter(item => item.id === model.id);
      
    }

    // Observable
    getNewData() {
      return this.API('GET', `data`)
    }

你為什么改變你的問題?

現在我們的答案不正確 - 不要這樣做

更新答案:

forkJoin(
 this.method1(),
 this.method2()
)
 .pipe(
   map(([data1, data2]) => {
     const filterData = [data1, data2]; // here will be some filtereing
     return filterData;
   }),
   mergeMap(filteredData => {
     // here you can append your filterData
     return this.getNewData(filteredData);
   })
 )
 .subscribe(console.log);

   getNewData(filterData) {
     return this.API('GET', filterData)
   }

演示: https://stackblitz.com/edit/typescript-j7rrwl?file=index.ts

您正在嘗試不鼓勵的嵌套訂閱。

如果調用彼此完全獨立,您可以將 append this.API('GET', 'data')調用作為forkJoin function 的第三個參數。

 import { forkJoin } from 'rxjs'; newData = []; forkJoin( this.method1(), this.method2(), this.API('GET', `data`) ).subscribe([ data1, data2, newData ]) => { const filteredData = data1.filter(item => item.id === model.id); this.newData = newData; console.log(this.newData); }

或者,如果 API 調用以某種方式依賴於前兩種方法的數據,那么您可以使用 RxJS 高階映射運算符之一,例如switchMap

import { forkJoin } from 'rxjs';
import { swithcMap } from 'rxjs/operators';

newData = [];

forkJoin(
  this.method1(),
  this.method2()
).pipe(
  switchMap(([data1, data2]) => {
    const filteredData = data1.filter(item => item.id === model.id);
    return this.getNewData(filteredData);
  })
).subscribe(newData => {
  this.newData = newData;
  console.log(this.newData);
}

getNewData (filteredData): Observable<any> {
  return this.API('GET', `data/${filteredData.id}`).pipe(
    map((resp: any) => {
      this.newData = resp;
    })
  );
}

更新(根據 OP 的更新)

  1. 您希望在另一個 HTTP 調用中使用來自forkJoin的 output。 然后你需要switchMap操作符,如圖所示。

  2. (與問題無關)當您更新原始帖子中的內容時,請嘗試提供這樣的注釋。 它使您更容易理解您的意圖。

使用combineLatest中的 combineLatest 並使用filter(), tap()檢查數據

combineLatest(
    this.method1(),
    this.method2(),
    this.getNewData()
).pipe(
    filter(data => !!data), 
    tap(data => console.log(data)) 
    catchError(error => console.log(error))
).subscribe(
  [dataFromMethod1, dataFromMethod2, dataFromMethod3] => {
   // This will subscribe only if all the observables return data
   // Otherwise it will go to catchError
})


// Filter will check if the data is present or not.
// Tap will return the data before subscribing
// catchError ==> Subscription errors are caught in this catchError

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM