多个 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)
}
})
)
我写的 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)
}
})
)