我有一个效果,可能会也可能不会发送动作:
handleMainAccount$ = createEffect(() => {
return this._actions$.pipe(
ofType(setUserDetails),
tap( (details) => {
if (details?.mainAccount) {
const fakeData = { foo: 'bar'};
this._accountHttpSvc.updateAccount(fakeData).pipe(
take(1), // so we don't have to unsub
map((res) => {
this._userStore.dispatch(setMainAccount({fakeData}));
}),
).subscribe();
}
// else
// we are not dispatching any action
})
);
} , { dispatch: false } ); // setting as false, because we may or may not dispatch an action
Run Code Online (Sandbox Code Playgroud)
我将调度设置为 false,因为有时此效果可能不会调度操作。这是不好的做法吗?如果有的话会有什么负面影响?
恕我直言,这是一个不好的做法。我将效果分为两类:
你的有点“两者”。如果需求发生变化,测试和管理就会变得更加困难。
另外,您在效果内手动订阅:这也是一个不好的做法!使用此代码,您无法获得展平运算符所具有的控制级别(例如,取消先前的请求)。
作为一般指南,假设您遇到以下情况:
map(action => condition ? otherAction : null)
Run Code Online (Sandbox Code Playgroud)
这显然不起作用,因为这null不是有效的操作。
因此,更改map为switchMap(或另一个展平运算符)并按如下方式修改代码:
import { switchMap, of, EMPTY } from 'rxjs';
...
switchMap(action => condition ? of(otherAction) : EMPTY)
Run Code Online (Sandbox Code Playgroud)
在您的场景中,您希望有条件地执行请求。它会是这样的而不是你的tap:
switchMap(condition => {
if (!condition) {
return EMPTY
}
return this.service.update(...).pipe(
take(1),
map(x => yourAction())
)
})
Run Code Online (Sandbox Code Playgroud)
显然,您可以使用任何其他展平运算符来代替switchMap。对于switchMap并发请求,将取消前一个请求,它们mergeMap将被并行处理,concatMap它们将排队,exhaustMap如果前一个调用尚未完成,则第二个请求将不起作用。
| 归档时间: |
|
| 查看次数: |
3048 次 |
| 最近记录: |