#### 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 打包部署后訪問頁面白屏