Ngrx/Effects中使用switchMap分发Action失败但map正常工作的原因探究
为什么NgRx Effects中switchMap无法分发Action而map可以?
这其实是RxJS中map和switchMap两个操作符的核心差异导致的,我来给你拆解清楚:
核心区别:返回值要求不同
map是值转换操作符:它接收上游流中的每一个值,返回一个普通的JavaScript值(这里就是你的Action对象)。RxJS会自动把这个返回值包装成一个新的Observable,NgRx Effects也能识别这种流,所以你的代码能正常运行。switchMap是Observable投影操作符:它要求你返回的是一个ObservableInput类型的值——简单说就是必须是Observable、Promise、数组/Iterable这类可被RxJS转化为Observable的类型,而不能是普通的Action对象。你现在直接返回Action,TypeScript就会报错,提示你返回的对象缺少[Symbol.iterator](这是Iterable类型必须的符号,普通Action没有),所以不符合switchMap的参数要求。
解决方法(如果一定要用switchMap)
如果你的场景确实需要用switchMap(比如后续要加异步操作,比如请求API),只需要把返回的Action用RxJS的of()操作符包装成Observable就行:
import { of } from 'rxjs'; // ... GetAllStaffFromStore = createEffect(() => this.action$.pipe( ofType(adminActions.FetchAllStaffFromStore), concatLatestFrom((action) => this.store.select(fromAdminReducer.selectStaff)), switchMap(([action, staff]) => { if (staff.length === 0) { // 用of()把Action包装成Observable return of(adminActions.GetAllStaffStart({ per_page: action.per_page })); } else { // 同样包装自定义Action return of({ type: "Getting Staff From Store" }); } }) ));
什么时候用map,什么时候用switchMap?
- 如果你只是同步判断后返回单个Action,用
map就足够了,代码更简洁,也符合Effects的常规用法。 - 只有当你需要在操作符内部做异步操作(比如HTTP请求、Promise),或者需要发射多个Action时,才需要用
switchMap(或者mergeMap、concatMap这类投影操作符),这时候一定要确保返回的是Observable类型。
内容的提问来源于stack exchange,提问作者walexy
相关产品推荐
相关产品推荐

