Redux React中如何让yield put变为阻塞式,待其执行完成后再运行后续逻辑
解决方案
redux-saga 中默认的 yield put 为非阻塞调用,不会等待action被reducer处理完成、store更新后再执行后续逻辑,针对你的滚动加载场景,有以下3种可行方案:
方案1:直接使用本地计算的新页码(最简单高效)
你在调用put之前已经算出了新的页码值,完全可以直接把这个值传给API请求逻辑,不需要依赖store更新后的值:
const newPage = page_number + 1 yield put(ActionCreator.setPageNumber(newPage)); // 直接用本地的newPage发起请求,无需等待store更新 yield call(fetchTableData, newPage);
该方案没有额外的监听逻辑,性能最高,完全适配你当前的需求。
方案2:使用阻塞式put.resolve(要求redux-saga版本≥1.0.0)
redux-saga 提供了阻塞版本的put方法put.resolve,会等待当前action被reducer处理完成、所有关联的副作用执行完毕后,才会继续执行后续代码:
// 这里会阻塞,直到页码完全更新到store中 yield put.resolve(ActionCreator.setPageNumber(page_number + 1)); // 此时从store中取到的页码已是最新值 const latestPage = yield select(state => state.table.pageNumber); yield call(fetchTableData, latestPage);
方案3:拆分逻辑,监听页码变更触发请求
如果你的页码更新触发源不止滚动加载,需要更高的复用性,可以把逻辑拆分为两部分:
- 滚动触发的saga仅负责更新页码
function* handleScrollLoad() { yield put(ActionCreator.setPageNumber(page_number + 1)); }
- 单独启动一个监听saga,每次监听到页码更新的action后,自动发起数据请求
function* watchPageNumberChange() { // takeLatest会自动取消之前未完成的旧请求,避免旧数据覆盖新数据 yield takeLatest(ActionCreator.setPageNumber.type, function* (action) { const newPage = action.payload; yield call(fetchTableData, newPage); }) }
内容的提问来源于stack exchange,提问作者rudeTool
相关产品推荐
相关产品推荐

