如果当前订阅未完成可重复观察,则取消新订阅



我有一个史诗般的动作,它从本地服务器获取公司,以 React 组件的componentDidMount方法调度。 使用返回的数据,我实例化模型并将它们传递给完成其工作的化简器。

史诗动作如下所示:

export const fetchCompaniesEpic = (action$: Observable<Action>): Observable<Action> =>
action$.pipe(
ofType(FETCH_COMPANIES),
delay(5000),
switchMap((action: any) =>
ajax(COMPANIES_RESOURCE_URL).pipe(
map((data: any) =>
data.response.map((value: any) => new Company(value.symbol, value.name, value.lastSale, value.marketCap, value.sector, value.industry))
),
map((companies: Company[]) => fetchCompaniesFulfilled(companies))
)
)
);

作为redux-observable新手,我想向大家提出3个问题:

1(取消当前订阅仍在进行中时发生的所有新订阅(以及http请求(的最佳方法是什么?(进行中也指在延迟 5 秒期间(

2(实现我所有目标的最佳方法是什么?我是否在做任何不好的做法或任何可以做得更好的事情?(rxjs, react, redux(

3( 在我发送此操作的位置订阅的最佳方式是什么?类似dispatch({type: FETCH_COMPANIES}).subscribe

附言这只是一个理论示例,因为我想很好地理解它是如何工作的,所以不要关注延迟等的真正效用......

为了更详细地说明@Xinan所写的内容,您可以考虑以下示例,该示例旨在模拟您的情况

const action$ = new Subject<number>();
const ajax = (delay: number) => {
const ajax$ = new Subject<any>();
setTimeout(() => {
ajax$.next('delay ' + delay);
ajax$.complete();
}, delay);
return ajax$.asObservable();
};
action$
.pipe(
switchMap(delay => ajax(delay)),  // delay 1001, delay 1002
// exhaustMap(delay => ajax(delay)),  // delay 3000, delay 1002
)
.subscribe(console.log);
setTimeout(() => {action$.next(3000);}, 0);  // action$ emission 1
setTimeout(() => {action$.next(1000);}, 1000);  // action$ emission 2 
setTimeout(() => {action$.next(1001);}, 1500); // action$ emission 3
setTimeout(() => {action$.next(1002);}, 3502); // action$ emission 4

action$可观察量分别在 0、1000、1500 和 3502 毫秒后发出 4 次。

每次action$发出时,我们都会创建一个ajaxObservable,该 Observable 本身只会在指定为action$参数的延迟之后发出一次,然后完成。

因此,例如,由第一个action$通知(即action$ 排放1(创建的ajaxObservable 将在 3 秒后发出并将完成,而第二个ajaxObservable 将在 2 秒后发出(1 秒由于action$发射延迟 2 + 1 秒由于ajax发射的延迟(。

在此模拟中,如果您使用switchMap,在控制台上您将看到

delay 1001
delay 1002

原因是 action$ 排放 3 发出,而 action$ 排放 1 和 action$ 排放2 仍在飞行,因此它们由action$排放 3完成并取消订阅switchMap的逻辑。操作 $ 排放 4次发射后,没有其他操作 $ 排放,因此可以正常完成,因此diplay 1002打印在控制台上。

相反,如果你用exaustMap代替switchMap,你会得到

delay 3000
delay 1002

原因是前面推理的镜子。行动$排放2和行动$排放3被杀死,因为行动$排放1仍在飞行。

我猜你需要的是exaustMap,基本上它的作用与switchMap相反

switchMap取消前一个并取

新的exaustMap取消新的并维护现有的(如果尚未完成(

最新更新