观看者在redux-saga中的意义是什么?

Sai*_*tta 3 reactjs redux redux-saga

我刚接触redux-saga,对Watchers和Generators有点困惑

以下面的代码为例,这是我的sagas文件的入口点

function* employeesSaga() {
    yield all([
        takeEvery(getType(employeeActions.login.request), handleLoginRequest),
        takeEvery(getType(employeeActions.verifyLogin.request), handleVerifyLoginRequest),
        takeEvery(getType(employeeActions.logout), handleLogout)
    ]);
}
Run Code Online (Sandbox Code Playgroud)

我直接将每个redux调用连接到相应的处理程序。

但是有些人使用观察者,然后他们在该生成器中调用处理程序。这样做的目的是什么?我应该使用那种模式吗?

另外,我注意到有些人用来包装整个处理程序,这while(true)是必要的吗?因为我的代码也可以正常工作...

And*_*eev 6

关于第一个问题

这可能只是可读性问题。

观察者不是真正的“模式”,它们只是使您的代码更加明确地表明其意图:

function* watchLoginRequest() {
    yield takeEvery(getType(employeeActions.login.request), handleLoginRequest)
}

function* watchVerifyLoginRequest() {
    yield takeEvery(getType(employeeActions.verifyLogin.request), handleVerifyLoginRequest)
}

function* watchLogout() {
    yield takeEvery(getType(employeeActions.logout), handleLogout)
}

function* startWatchers() {
    yield call(watchLoginRequest)
    yield call(watchVerifyLoginRequest)
    yield call(watchLogout)
}

function* employeesSaga() {
    yield call(startWatchers)
}
Run Code Online (Sandbox Code Playgroud)

第二个问题

可能您正在谈论这种流程:

function* watchLoginRequest() {
    while (true) {
        const action = take(getType(employeeActions.login.request))
        yield call(handleLoginRequest, action)
    }
}
Run Code Online (Sandbox Code Playgroud)

区别:

  • 一段时间(真)-Take呼叫流程不允许执行单个处理器的两个实例兼任。它需要执行一个操作,然后阻止该呼叫,直到handleLoginRequest()完成。如果用户在处理程序完成之前单击登录按钮,则会错过相应的操作。

  • takeEvery()流量确实允许并行处理程序的执行。这可能不是您想要的。

Redux-saga文档讲述了如何takeEvery()在后台实现

const takeEvery = (patternOrChannel, saga, ...args) => fork(function*() {
  while (true) {
    const action = yield take(patternOrChannel)
    yield fork(saga, ...args.concat(action))
  }
})
Run Code Online (Sandbox Code Playgroud)

您会看到,takeEvery()它本身是非阻塞的(派生的),并且以非阻塞的方式执行处理程序(派生的)。

第三种选择

还有takeLatest(),它确实允许并发处理程序执行,但是如果存在处理程序的先前实例,则将其取消。Redux-saga文档也提供了其内部实现。

一段时间(真)-Take呼叫是最好的登录流程,我想。您可能不希望并发登录。但是,如果在UI级别上阻止并发登录,则这些流程是等效的,但是while(true)-take-call是最明确和可读的。