多个 API 调用出现问题

Trouble with Multiple API Calls

我写的 ngrx 效果有一些问题,它应该通过多个 API 调用检索信息。出于某种原因,它随机检索一些成功的调用,但其他调用,它只是返回为 null。

效果:

 @Effect()
  loadMoveList$: Observable<Action> = this.actions$.pipe(
    ofType(pokemonActions.PokemonActionTypes.SetSelectedGame),
    withLatestFrom(
      this.store$.select(pokemonSelectors.getMoveLists), 
      this.store$.select(pokemonSelectors.getSelectedGame),
      ),
    map(([action, moveLists, selectedGame])=> {
      let newMoveList = []
      if(moveLists[selectedGame][0].moveInfo === null){
        moveLists[selectedGame].map(_move=>{
          newMoveList.push({..._move, moveInfo: this.pokemonService.getMove(_move.moveUrl)}as Move)
        })
      }
      const newMoveLists = {...moveLists, [selectedGame]: newMoveList} as MoveLists
      return new pokemonActions.LoadMoveListSuccess(newMoveLists)
    })
  )

服务 getMove() 代码:

getMove(moveUrl:string):Observable<MoveInfo>{
    if(this.movesCache[moveUrl]){
      return this.movesCache[moveUrl];
    }
    else{
      this.movesCache[moveUrl] = this.httpClient.get<MoveInfo>(moveUrl).pipe(
        shareReplay(1),
        catchError(err=>{
          delete this.movesCache[moveUrl];
          console.log(err);
          return EMPTY;
        }));
    }
  }

我会重构服务方法getMove(),

return this.movesCache[moveUrl];

没有返回一个 observable 并且在你的 else 块中你没有返回 http get 调用的结果。

重构服务方法

getMove(moveUrl:string):Observable<MoveInfo>{
    if(this.movesCache[moveUrl]){
      return of(this.movesCache[moveUrl]);
    }
    else{
      return this.httpClient.get<MoveInfo>(moveUrl).pipe(
        tap(move => this.moveCache[moveUrl] = move),
        catchError(err=>{
          delete this.movesCache[moveUrl];
          console.log(err);
          throwError(err.message)
        }));
    }
  }

重构效果。

 @Effect()
  loadMoveList$: Observable<Action> = this.actions$.pipe(
    ofType(pokemonActions.PokemonActionTypes.SetSelectedGame),
    withLatestFrom(
      this.store$.select(pokemonSelectors.getMoveLists), 
      this.store$.select(pokemonSelectors.getSelectedGame),
      ),
    switchMap(([action, moveLists, selectedGame])=> {
      let apiCalls = [];
      if(moveLists[selectedGame][0].moveInfo === null) {
        apiCalls = [moveLists[selectedGame].map(_move=> this.pokemonService.getMove(_move.moveUrl)]
        return forkJoin(...apiCalls).pipe(
          map((response) => {
            let newMoveLists = moveLists[selectedGame].map((_move, index) => {
              return { ..._move, moveInfo: response[index] }
            })
            return new pokemonActions.LoadMoveListSuccess(newMoveLists)
          })
        )
      } else {
        const newMoveLists = {...moveLists, [selectedGame]: []} as MoveLists
        return new pokemonActions.LoadMoveListSuccess(newMoveLists)
      }
    })
  )