无法理解 Redux-Saga 中的非阻塞调用
Unable to understand non-blocking calls in Redux-Saga
我正在尝试理解 redux-saga
文档的 Non-blocking calls 部分并坚持使用以下代码
import { fork, call, take, put } from 'redux-saga/effects'
import Api from '...'
function* authorize(user, password) {
try {
const token = yield call(Api.authorize, user, password)
yield put({type: 'LOGIN_SUCCESS', token})
yield call(Api.storeItem, {token})
} catch(error) {
yield put({type: 'LOGIN_ERROR', error})
}
}
function* loginFlow() {
while (true) {
const {user, password} = yield take('LOGIN_REQUEST')
yield fork(authorize, user, password)
yield take(['LOGOUT', 'LOGIN_ERROR'])
yield call(Api.clearItem, 'token')
}
}
解释说
If the authorize fails before the user logs out, it will dispatch a LOGIN_ERROR action, then terminate. So loginFlow will take the LOGIN_ERROR before the LOGOUT then it will enter in a another while iteration and will wait for the next LOGIN_REQUEST action.
我真的无法理解语句 所以 loginFlow 将在 LOGOUT 之前使用 LOGIN_ERROR 然后它将进入另一个 while 迭代并等待下一个 LOGIN_REQUEST行动.
谁能解释一下yield put({type: 'LOGIN_ERROR', error})
和yield take(['LOGOUT', 'LOGIN_ERROR'])
之间的关系?
yield put({type: 'LOGIN_ERROR', error})
- 调度 LOGIN_ERROR
.
类型的操作
yield take(['LOGOUT', 'LOGIN_ERROR'])
暂停生成器函数 (loginFlow
) 执行,直到调度 LOGOUT
或 LOGIN_ERROR
类型的操作。
简单说明一下:
yield put({type: 'LOGIN_ERROR',error})
= dispatch action 表示有一个 LOGIN_ERROR.
yield take(['LOGOUT', 'LOGIN_ERROR'])
= 等到有一个 LOGOUT 或 LOGIN_ERROR 动作被调度,并且只有在有一个 LOGOUT 或 [= 时才继续执行下一行 yield call(Api.clearItem, 'token')
21=]
非阻塞
是一个Synchronous flow,也就是说Saga违背代码块,同时读取父块内的行,所以叫Non-Blocking
阻塞
调用意味着 Saga 产生了一个 Effect 并等待前一个块,然后它继续执行下一个块,基本上它被称为 Blocking
对于你的情况,你只是误解了 redux-saga 的文档,但它就像 this
import {call, cancel, join, take, put} from "redux-saga/effects"
function* saga() {
yield take(ACTION) // Blocking: will wait for the action
yield call(ApiFn, ...args) // Blocking: will wait for ApiFn (If ApiFn returns a Promise)
yield call(otherSaga, ...args) // Blocking: will wait for otherSaga to terminate
yield put(...) // Non-Blocking: will dispatch within internal scheduler
const task = yield fork(otherSaga, ...args) // Non-blocking: will not wait for otherSaga
yield cancel(task) // Non-blocking: will resume immediately
// or
yield join(task) // Blocking: will wait for the task to terminate
}
有关更多信息,请阅读 Redux-Saga
的文档本身
我正在尝试理解 redux-saga
文档的 Non-blocking calls 部分并坚持使用以下代码
import { fork, call, take, put } from 'redux-saga/effects'
import Api from '...'
function* authorize(user, password) {
try {
const token = yield call(Api.authorize, user, password)
yield put({type: 'LOGIN_SUCCESS', token})
yield call(Api.storeItem, {token})
} catch(error) {
yield put({type: 'LOGIN_ERROR', error})
}
}
function* loginFlow() {
while (true) {
const {user, password} = yield take('LOGIN_REQUEST')
yield fork(authorize, user, password)
yield take(['LOGOUT', 'LOGIN_ERROR'])
yield call(Api.clearItem, 'token')
}
}
解释说
If the authorize fails before the user logs out, it will dispatch a LOGIN_ERROR action, then terminate. So loginFlow will take the LOGIN_ERROR before the LOGOUT then it will enter in a another while iteration and will wait for the next LOGIN_REQUEST action.
我真的无法理解语句 所以 loginFlow 将在 LOGOUT 之前使用 LOGIN_ERROR 然后它将进入另一个 while 迭代并等待下一个 LOGIN_REQUEST行动.
谁能解释一下yield put({type: 'LOGIN_ERROR', error})
和yield take(['LOGOUT', 'LOGIN_ERROR'])
之间的关系?
yield put({type: 'LOGIN_ERROR', error})
- 调度 LOGIN_ERROR
.
yield take(['LOGOUT', 'LOGIN_ERROR'])
暂停生成器函数 (loginFlow
) 执行,直到调度 LOGOUT
或 LOGIN_ERROR
类型的操作。
简单说明一下:
yield put({type: 'LOGIN_ERROR',error})
= dispatch action 表示有一个 LOGIN_ERROR.yield take(['LOGOUT', 'LOGIN_ERROR'])
= 等到有一个 LOGOUT 或 LOGIN_ERROR 动作被调度,并且只有在有一个 LOGOUT 或 [= 时才继续执行下一行yield call(Api.clearItem, 'token')
21=]
非阻塞
是一个Synchronous flow,也就是说Saga违背代码块,同时读取父块内的行,所以叫Non-Blocking
阻塞
调用意味着 Saga 产生了一个 Effect 并等待前一个块,然后它继续执行下一个块,基本上它被称为 Blocking
对于你的情况,你只是误解了 redux-saga 的文档,但它就像 this
import {call, cancel, join, take, put} from "redux-saga/effects"
function* saga() {
yield take(ACTION) // Blocking: will wait for the action
yield call(ApiFn, ...args) // Blocking: will wait for ApiFn (If ApiFn returns a Promise)
yield call(otherSaga, ...args) // Blocking: will wait for otherSaga to terminate
yield put(...) // Non-Blocking: will dispatch within internal scheduler
const task = yield fork(otherSaga, ...args) // Non-blocking: will not wait for otherSaga
yield cancel(task) // Non-blocking: will resume immediately
// or
yield join(task) // Blocking: will wait for the task to terminate
}
有关更多信息,请阅读 Redux-Saga
的文档本身