while true 在 redux sage 中是否仅适用于长轮询或其他用例?
Is while true in a redux sage only for long polling or for other use cases?
我通常会猜测 redux-saga while(true) 将用于长轮询,我看到其他关于长轮询的帖子。但是,我加入了一个项目,我看到大约 44 个带有 while(true) 的 sagas,这似乎意味着没有办法对这个项目进行长轮询(我猜一个典型的项目将是 1 或最多 2 个长轮询来收集一次拍摄所有信息)。这是一个例子...
function* enrollAddContactSaga() {
while (true) {
const { username, appName } = yield take(ENROLL_ADD_CONTACT);
const newUserId = uuidv4();
yield put(enrolllNewContact(newUserId, username));
const { contactAddSuccess, contactAddFailure } = yield race({
contactAddSuccess: take(ENROLL_NEW_CONTACT_ADD_SUCCESS),
contactAddFailure: take(ENROLL_NEW_CONTACT_ADD_FAILURE),
});
if (contactAddSuccess) {
yield put(enrollCheckCredentialStatus({ username, appName }));
} else {
yield put(
showAlert('Oops!', buildErrorMessage(contactAddFailure), 'error'),
);
}
}
}
有人可以解释一下吗? while(true) 有什么用?
我真的认为框架会不断调用它,唯一会中断的是在远程调用期间,一旦 returns,传奇 returns,因为它永远不会完成后,它会再次调用该方法。
注意:我也没有在生成器 saga 函数中看到任何 return 语句来使它完成。
基本上,如果您希望在应用程序的生命周期内(或直到被父传奇取消)运行 的传奇,没有 break
的 while(true)
很有用。通常这是因为这个 saga 负责监听一些事件,而这些事件永远不会停止相关。
在您的特定代码中,传奇进入循环,然后立即 yield
s 直到 ENROLL_ADD_CONTACT
动作发生。 saga 不需要为此进行轮询,redux saga 将检查任何已分派的操作,并在必要时唤醒您的 saga。如果该动作从未发生,那么您的 saga 将永远暂停。假设该操作确实发生了,您的 saga 将在那时恢复执行。
作为 saga 运行 的其余部分,它将执行其他一些异步操作,在此期间它不会监听更多 ENROLL_ADD_CONTACT
操作。所以假设,如果其中一个动作发生在这段时间内,它将被忽略。最终,到达循环的末尾并循环回到顶部,此时它再次开始侦听动作。
换句话说,您展示的代码实现了与 takeLeading 非常相似的东西,只是在一个 saga 中,而不是分成两个。因此可以像这样实现类似的行为:
function* enrollAddContactSaga() {
yield takeLeading(ENROLL_ADD_CONTACT, someOtherSaga);
}
function* someOtherSaga(action) {
const { username, appName } = action;
const newUserId = uuidv4();
yield put(enrolllNewContact(newUserId, username));
const { contactAddSuccess, contactAddFailure } = yield race({
contactAddSuccess: take(ENROLL_NEW_CONTACT_ADD_SUCCESS),
contactAddFailure: take(ENROLL_NEW_CONTACT_ADD_FAILURE),
});
if (contactAddSuccess) {
yield put(enrollCheckCredentialStatus({ username, appName }));
} else {
yield put(
showAlert('Oops!', buildErrorMessage(contactAddFailure), 'error'),
);
}
}
我通常会猜测 redux-saga while(true) 将用于长轮询,我看到其他关于长轮询的帖子。但是,我加入了一个项目,我看到大约 44 个带有 while(true) 的 sagas,这似乎意味着没有办法对这个项目进行长轮询(我猜一个典型的项目将是 1 或最多 2 个长轮询来收集一次拍摄所有信息)。这是一个例子...
function* enrollAddContactSaga() {
while (true) {
const { username, appName } = yield take(ENROLL_ADD_CONTACT);
const newUserId = uuidv4();
yield put(enrolllNewContact(newUserId, username));
const { contactAddSuccess, contactAddFailure } = yield race({
contactAddSuccess: take(ENROLL_NEW_CONTACT_ADD_SUCCESS),
contactAddFailure: take(ENROLL_NEW_CONTACT_ADD_FAILURE),
});
if (contactAddSuccess) {
yield put(enrollCheckCredentialStatus({ username, appName }));
} else {
yield put(
showAlert('Oops!', buildErrorMessage(contactAddFailure), 'error'),
);
}
}
}
有人可以解释一下吗? while(true) 有什么用?
我真的认为框架会不断调用它,唯一会中断的是在远程调用期间,一旦 returns,传奇 returns,因为它永远不会完成后,它会再次调用该方法。
注意:我也没有在生成器 saga 函数中看到任何 return 语句来使它完成。
基本上,如果您希望在应用程序的生命周期内(或直到被父传奇取消)运行 的传奇,没有 break
的 while(true)
很有用。通常这是因为这个 saga 负责监听一些事件,而这些事件永远不会停止相关。
在您的特定代码中,传奇进入循环,然后立即 yield
s 直到 ENROLL_ADD_CONTACT
动作发生。 saga 不需要为此进行轮询,redux saga 将检查任何已分派的操作,并在必要时唤醒您的 saga。如果该动作从未发生,那么您的 saga 将永远暂停。假设该操作确实发生了,您的 saga 将在那时恢复执行。
作为 saga 运行 的其余部分,它将执行其他一些异步操作,在此期间它不会监听更多 ENROLL_ADD_CONTACT
操作。所以假设,如果其中一个动作发生在这段时间内,它将被忽略。最终,到达循环的末尾并循环回到顶部,此时它再次开始侦听动作。
换句话说,您展示的代码实现了与 takeLeading 非常相似的东西,只是在一个 saga 中,而不是分成两个。因此可以像这样实现类似的行为:
function* enrollAddContactSaga() {
yield takeLeading(ENROLL_ADD_CONTACT, someOtherSaga);
}
function* someOtherSaga(action) {
const { username, appName } = action;
const newUserId = uuidv4();
yield put(enrolllNewContact(newUserId, username));
const { contactAddSuccess, contactAddFailure } = yield race({
contactAddSuccess: take(ENROLL_NEW_CONTACT_ADD_SUCCESS),
contactAddFailure: take(ENROLL_NEW_CONTACT_ADD_FAILURE),
});
if (contactAddSuccess) {
yield put(enrollCheckCredentialStatus({ username, appName }));
} else {
yield put(
showAlert('Oops!', buildErrorMessage(contactAddFailure), 'error'),
);
}
}