使用RxJS轮询Node.js服务器获取数据后无法更新应用状态求助
问题解答
为什么dispatcher需要返回Observable
这是RxJS结合类Redux状态管理架构的标准设计:
- Observable可以承载异步、多值的返回结果,完美适配轮询这类会持续产生新数据的场景(Promise只能返回单次结果,无法满足轮询需求)
- 上层架构会统一订阅所有dispatcher返回的Observable,自动把流中吐出的每一个值作为action传递给reducer,不需要手动编写回调、手动触发dispatch,减少异步逻辑的冗余代码
当前状态不更新的核心原因
你当前代码存在3个问题,导致状态无法正常更新:
- poll_server返回的流中吐出的是服务端原始响应数据,不是符合reducer要求的带
type字段的action对象,reducer识别不到合法的action类型,直接走default分支返回原状态 - reducer调用
init_state时传入的是整个action对象,而init_state接收的参数是服务端返回的warnings数据,参数不匹配导致状态初始化错误 - 额外问题:你当前轮询间隔设置的是3000ms(3秒),和你预期的0.5秒更新不匹配,且没有加请求错误处理,请求失败会直接导致轮询流终止
修复后的代码示例
dispatcher.js 修改
import { from, of, timer } from 'rxjs' import { concatMap, map, catchError } from 'rxjs/operators' import { FRONT_PAGE } from './constants' const poll_server = url => { // 轮询间隔改为500ms即0.5秒,匹配服务端更新频率 return timer(0, 500) .pipe(concatMap(() => from(fetch(url)) .pipe( map(response => { // 先判断请求是否成功 if (!response.ok) throw new Error(`请求失败:${response.status}`) return response.json() }), // 将服务端返回的warnings包装成合法action map(warnings => ({ type: FRONT_PAGE, payload: warnings })), // 错误处理,避免单次请求失败导致整个轮询流中断 catchError(err => of({ type: 'POLL_ERROR', payload: err.message })) ) ) ) } export const server_dispatch = action => { switch (action.type) { case FRONT_PAGE: { const res = poll_server('http://localhost:8080/warnings') console.log(res) // 这里打印的是Observable对象,不是响应数据 return res } default: return of(action) } }
reducer.js 修改
export function reduce(state, action) { switch (action.type) { case FRONT_PAGE: console.log(`REDUCER CALLED WITH ACTION ${FRONT_PAGE},最新数据:`, action.payload) // 传入服务端返回的warnings数据,而非整个action return init_state(action.payload) case 'POLL_ERROR': // 可根据需求添加错误状态处理 return {...state, error: action.payload} default: return state } }
内容的提问来源于stack exchange,提问作者kakakakakakakk
相关产品推荐
相关产品推荐

