如何使用redux-saga的delay实现每2秒调用一次接口的功能
Redux-saga 每2秒轮询接口实现方案
首先先从 redux-saga/effects 引入 delay 方法,这是saga内置的定时器工具,调用后会暂停generator执行指定的毫秒数。
基础实现(无限轮询)
直接在原有逻辑外层加无限循环,每次请求完成后等待2秒再执行下一次,这种方式不会出现请求堆积:
import { call, put, delay } from 'redux-saga/effects'; export function* getMyMeetings(action:any) { // 无限循环实现重复执行 while(true) { let {auth_uid} = action; const meetings = yield call( getData, 'get', `api/notes/by-user/${auth_uid}` ); yield put(putMeetings(meetings)); // 等待2秒后进入下一次循环 yield delay(2000); } }
如果需要严格保证两次请求的发起时间间隔为2秒,不管上次请求有没有返回,可以把yield delay(2000)放到while循环的第一行。
带终止功能的轮询(推荐生产环境使用)
无限轮询容易导致内存泄漏,通常需要支持手动终止(比如用户离开对应页面时停止轮询),可以配合race和take实现:
import { call, put, delay, take, race } from 'redux-saga/effects'; export function* pollMyMeetings(action:any) { while(true) { let {auth_uid} = action; const meetings = yield call( getData, 'get', `api/notes/by-user/${auth_uid}` ); yield put(putMeetings(meetings)); // 竞态逻辑:要么等2秒继续轮询,要么收到停止动作直接终止循环 const { stop } = yield race({ wait: delay(2000), stop: take('STOP_POLL_MEETINGS') }); if (stop) break; } }
在rootSaga中注册监听逻辑,用takeLatest保证同一时间只有一个轮询任务在运行:
import { takeLatest } from 'redux-saga/effects'; function* rootSaga() { yield takeLatest('START_POLL_MEETINGS', pollMyMeetings); }
需要停止轮询的时候,只需要dispatch一个type为STOP_POLL_MEETINGS的action即可。
核心逻辑说明
delay(2000)本质是返回一个2秒后resolve的Promise,generator执行到这里会主动暂停,到期后自动恢复执行while(true)配合yield可以实现可控的无限循环,不会像普通js的死循环一样卡住线程- 用
race实现的终止逻辑可以避免页面卸载后仍在后台请求的问题
内容的提问来源于stack exchange,提问作者underdog
相关产品推荐
相关产品推荐

