#### 1、实现方法
```javascript
/**
* 向指定api循环发送发送请求
* @param {string} apiName api名称
* @param {object=} data 请求参数(可选)
* @param {Function} cb 处理响应数据的回调
* @param {number=} interval 轮询间隔(毫秒)(可选,默认为配置值)
* @return {Object} 用于对轮询状态进行操作的实例
*/
export function fetchInterval(apiName, data, cb, emit, interval) {
const argumentsLength = arguments.length
const defaultInterval = config.get('fetchInterval')
if(argumentsLength === 2) {
// 只传了2个参数
// 没传data,没传interval
cb = data
data = null
interval = null
} else if(argumentsLength === 3) {
// 只传了3个参数
if(isFunction(cb)) {
// 没有传interval
interval = null
} else if(isNumber(cb)) {
// 没有传data
interval = cb
cb = data
data = null
}
}
data = data || {}
interval = interval || defaultInterval
let hasClosed = false
const delayFetchInterval = delay(
function() {
if(hasClosed) {
return
}
fetch(apiName, data, cb).then(res => {
emit(res)
delayFetchInterval()
})
// fetch(apiName, data, cb)
// .always(delayFetchInterval)
},
interval
)
delayFetchInterval(true)
return {
// 停止轮询
close() {
hasClosed = true
}
}
}
/**
* 创建channel对象
* @param {string} apiName api名称
* @param {Object=} data 请求参数(可选)
* @param {Function} cb 处理推送数据的回调
* @return {Function} websocket连接断开时需要执行的函数
*/
function* createEventChannel(apiName, data, cb) {
return eventChannel(emit => {
if(config.get('mock')){
fetchInterval(apiName, data, cb, emit)
return () => {}
}else{
const ws = new ReconnectingWebSocket(
apis.url(apiName, data)
)
ws.onmessage= (message) => emit({data: JSON.parse(message.data)})
return () => {
// ws.close();
};
}
});
}
/**
* 实例化Channel对象,并监听回调函数,根据回调分发action
* @param {string} apiName api名称
* @param {Object=} data 请求参数(可选)
* @param {Function} cb 处理推送数据的回调
* @return {void}
*/
export function fetchSocket(apiName, data, cb){
return function* (createAction) {
const channel = yield call(createEventChannel, apiName, data, cb);
while(true){
const res = yield take(channel);
yield put(createAction(res.data.result))
}
}
}
```
#### 2、代码说明
> 2.1 `fetchSocket`方法首先调用`createEventChannel`方法生成`Channel`对象,`createEventChannel`内部调用`redux-saga`提供的`eventChannel`方法,此方法提供一个带`emit`参数的回调函数,`emit`用于通知外部组件此函数执行结束并返回的结果,类似于`Promise`的`resolve`方法。所以,在`eventChannel`的回调函数里可以执行任何异步操作,在异步操作的回调函数里调用`emit()`方法,把结果作为参数返回即可。
> 2.2 `createEventChannel`成功返回了`Channel`对象,`const res = yield take(channel)`此段代码用于监听`emit`方法何时被触发,`res`便是从`emit`方法带回来的数据。
> 2.3 mock状态下,需要用`feterInterval`模拟socket,因此`feterInterval`方法中需要传入`emit`方法,以便于在每次`fetch`成功后可以触发`emit`成功返回数据。
#### 3、使用方法
`fetchSocket`是个高阶函数,调用时第一层跟往常一样,传入接口名称、参数、回调函数。第二层则传入生成`action`的方法。如下:
```javascript
const apifetchMenu = (workTableMenuSuccess) => {
return fetchSocket('fetchWorkTableLeftMenu')(workTableMenuSuccess)
}
/**
* 监听WORK_TABLE_MENU_REQUEST,调用对应API方法,请求数据
* @param {object} action 工作台左边导航的action对象
*/
export function* fetchWorkTableMenu() {
try {
yield take(WORK_TABLE_MENU_REQUEST)
yield call(apifetchMenu, workTableMenuSuccess)
} catch (error) {
yield put(requestFailed(error.message))
}
}
```
- 1、前端常用知识点
- 1.1 如何修改input的placeholder
- 1.2 如何修改滚动条默认样式
- 1.3 理解BFC
- 1.4 数字每隔三位加逗号
- 1.4.1 简单粗暴的做法
- 1.4.2 比较常用的方法
- 1.5 D3图表中如何让文字竖着显示
- 1.6 Handlebars模板中如何比较两个值
- 1.7 SVG/D3中字体特殊设置
- 1.8 Handlebars模板中序号从1开始排序
- 1.9 修改checkbox默认样式
- 1.10 D3.js 执行transition动画中断
- 2、执法项目
- 2.1 面积图填充为线条样式
- 2.2 一个paseFloat()方法两分钟就把页面卡死了
- 2.3 开发中常见的细节问题
- 3、迪爱斯项目
- 3.1 热点冰点卡死问题
- 3.2 ifream切换导致内存泄漏
- 3.3 D3文字旋转问题
- 3.4 D3图表提示框位置问题
- 3.5 js如何实现页面iframe事件监听
- 3.6 zTree-jQuery 树插件异步加载如何传参
- 3.7 图易加载无延迟隐藏部分页面组件
- 4、指挥大屏项目
- 4.1 长时间运行chrome浏览器奔溃问题
- 5、PC端指挥项目
- 5.1 地图上各区域添加图表并将图表显示在各区域中心位置
- 5.2 svg里面添加image标签该的width,height属性被压缩问题
- 5.3 地图上添加图表或文字后较小的区域无法钻取
- 5.4 svg添加image元素在谷歌低版本不显示
- 5.5 input输入框记住用户名或密码后样式被浏览器自带的样式覆盖
- 6、运维项目
- 6.1 按键F11页面无法缩放
- 6.2 主页面逆时针旋转的两段弧问题
- 6.3 websocket的close方法不起作用
- 7、汉阳项目
- 8、警务云项目
- 8.1 PKI兼容chrome浏览器问题
- 9、万达项目
- 9.1 直方图中出现数值比刻度值大
- 9.2 D3选择集的处理模版
- 9.3 将数字转化为三分位节法
- 9.4 制作简易X轴
- 10、涪陵项目
- 10.1 IE11部分版本浏览器下滚动条位置不对
- 11、昆明大屏展示
- 11.1第一期五个页面经验汇总
- 11.2防止文本越界
- 11.3SVG里面谨慎设置font-family
- 11.4Error: <rect> attribute height: A negative value is not valid
- 12、技侦动态管控
- 12.1 使用CSS3动画导致页面抖动
- 12.2 使用 digitroll数字滚动插件,给数字加逗号(3位数分隔)
- 13、ES6前端开发框架
- 13.1 打包后部署到Tomcat下访问路径不对
- 14、贵阳项目
- 14.1、关于引用不到saga文件报错的问题
- 15、React前端开发框架
- 15.1 this.refs.xxx获取到的值是undefined
- 15.2 Mockjs与mapbox不兼容
- 15.3 axios联调报跨域错误
- 15.4 saga结合websocket使用方法
- 15.5 打包部署后访问页面白屏