gpt4 book ai didi

javascript - 多次调用 sagaMiddleware.run 是否安全?

转载 作者:搜寻专家 更新时间:2023-10-30 21:47:28 25 4
gpt4 key购买 nike

我在应用程序中使用 redux 和 redux-saga 来管理状态和异步操作。为了让我的生活更轻松,我编写了一个基本上充当传奇经理的类,使用“注册”传奇的方法。这个 register 方法派生出新的 saga,并使用 redux-saga/effects/all 将它与所有其他已注册的 saga 结合起来:

class SagasManager {
public registerSaga = (saga: any) => {
this._sagas.push(fork(saga));
this._combined = all(this._sagas);
}
}

然后我的商店使用这个类来获取 _combined saga,据说是在所有 sagas 都注册之后:

const store = Redux.createStore(
reducer,
initialState,
compose(Redux.applyMiddleware(sagaMiddleware, otherMiddleware)),
);
sagaMiddleware.run(sagasManager.getSaga());

但是,我遇到了一个问题,即根据情况(如进口订单),这并不总是按预期工作。发生的事情是,在调用 sagaMiddleware.run 之前,一些 sagas 没有被注册。

我通过在 SagasManager 上提供回调来解决这个问题:

class SagasManager {
public registerSaga = (saga: any) => {
this._sagas.push(fork(saga));
this._combined = all(this._sagas);
this.onSagaRegister();
}
}

然后商店代码可以将其用作

sagasManager.onSagaRegister = () => sagaMiddleware.run(sagasManager.getSaga());

这似乎可行,但我无法在文档中找到这是否安全。我确实看到 .run 返回一个 Task,它有取消等方法,但是因为我的问题只是在商店构建和应用程序已呈现,我认为这不是问题。

谁能解释这是否安全,如果不安全,更好的解决方案是什么?

最佳答案

这可能取决于您所说的“安全”是什么意思。在这种情况下,您的意思到底是什么?

首先,这是 source of runSaga itself ,以及它被 saga 中间件使用的位置。

查看 runSaga 内部,我看到:

export function runSaga(options, saga, ...args) {
const iterator = saga(...args)

// skip a bunch of code

const env = {
stdChannel: channel,
dispatch: wrapSagaDispatch(dispatch),
getState,
sagaMonitor,
logError,
onError,
finalizeRunEffect,
}

const task = proc(env, iterator, context, effectId, getMetaInfo(saga), null)

if (sagaMonitor) {
sagaMonitor.effectResolved(effectId, task)
}

return task
}

我从中得到的是,当您调用 runSaga(mySagaFunction) 时,不会发生任何“破坏性”的事情。但是,如果您多次使用相同的 saga 函数调用 runSaga(),您可能会运行该 saga 的多个副本,这可能会导致您的应用程序不希望出现的行为。

您可能想尝试对此进行试验。例如,如果您有一个计数器应用并执行此操作,会发生什么情况?

function* doIncrement() {
yield take("DO_INCREMENT");
put({type : "INCREMENT"});
}

sagaMiddleware.runSaga(doIncrement);
sagaMiddleware.runSaga(doIncrement);

store.dispatch({type : "DO_INCREMENT"});

console.log(store.getState().counter);
// what's the value?

我猜计数器会是 2,因为 doIncrement 的两个副本都会响应。

如果这种行为令人担忧,那么您可能需要确保取消之前的 sagas。

不久前,我实际上遇到了一个在热重载期间取消 sagas 的方法,并且 included a version of that in a gist for my own usage .您可能想引用它以获取想法。

关于javascript - 多次调用 sagaMiddleware.run 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52324200/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com