如果当前的订阅未完成redux-observable,则取消新订阅

问题描述 投票:2回答:2

我有一个史诗般的动作,从本地服务器获取公司,在React组件的componentDidMount方法中发送。通过返回数据,我实例化模型并将它们传递给执行其工作的reducer。

史诗动作如下所示:

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的新手,我想向大家提出三个问题:

1)取消所有新订阅(以及http请求)的最佳方法是什么,同时当前的订阅仍在进行中? (进行中也意味着延迟5秒)

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

3)订阅此操作的最佳方式是什么?像dispatch({type: FETCH_COMPANIES}).subscribe之类的东西

附:这只是一个理论上的例子,因为我非常理解它是如何工作的,所以不要专注于延迟等的实际效用......

reactjs redux react-redux rxjs redux-observable
2个回答
1
投票

为了更详细地说明@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$ Observable分别在0,1000,1500和3502毫秒后发出4次。

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

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

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

delay 1001
delay 1002

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

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

delay 3000
delay 1002

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


0
投票

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

switchMap取消了前一个并取而代之

exaustMap取消新的并保留现有的,如果还没有完成

© www.soinside.com 2019 - 2024. All rights reserved.