當前位置:
首頁 > 知識 > 自定義事件解決重複請求BUG

自定義事件解決重複請求BUG

現在,組件化開發還是比較流行的,畢竟其優點相當突出。最近在開發一個組件的時候,遇到了一個很有意思的BUG。。。

BUG的背景

最近在開發一個組件,好不容易開發好了轉測試。然後,測試給我提了一個這樣的bug,orz...

自定義事件解決重複請求BUG

因為是一個組件,最大的好處就是可以隨處復用,隨處使用,然而,當一個頁面用了多個組件,只有最後一個生效的時候,這個組件就沒有什麼意義了。。。

BUG原因查找

這個組件的初始數據來源的介面是固定的,也就是說,頁面內的所有這個組件在初始化的時候都會發出同樣的請求,這裡的請求是jsonp的方式,所以回調函數是綁定在window上的一個函數,但是在頁面中window只有一個,所以在回調處理的時候,要處理的組件內的相應的數據只指向最後一個組件。所以導致多個同樣的組件在同一個頁面中,只有最後一個組件能在取得數據之後順利渲染出來。

BUG解決思路

最主要就是要將每次請求的callback存儲起來,這樣就可以保證callback中對組件數據的處理不是只指向最後一個。其次,既然是一樣的請求,當然不希望會發出兩次以上啦,即一個頁面發出的每一個請求都是唯一的。

BUG解決方案

想到了發布訂閱者模式的自定義事件,可以寫這樣的一個模塊,每次請求發出前判斷一下之前是否有相同的模塊已經發出了,如果沒有則緩存callback發出請求,如果有相同的請求已經發出了,那麼檢查一下這個發出的請求是否已經完成了,如果沒有則繼續緩存callback等待,如果請求已經發出並且已經完成則直接處理callback。在請求第一次回來後,發出廣播,把之前緩存的callback都執行一次。

自定義事件詳情

定義一個模塊,裡面有n個以回調函數命名的事件對象,每個對象有在被初始化的時候,定義其狀態state,對應的callback數組,請求回到的數據data。每次調用該模塊,首先檢查對應的cbName是否被初始化,然後檢查其state。根據state做相應的操作並改變state的值。state的值有3中,分別為init、loading、loaded。即初始化、請求中、請求完成。處於請求完成狀態時才能執行相應的回調。具體如下:

define("wq.getData", function (require, exports, module) {
var ls = require("loadJs");

var cache = {};
cache.init = function(cb,cbName,url){
if(!cache[cbName]){
cache[cbName] = {};
cache[cbName].state = "init";
cache[cbName].cbs = ;
cache[cbName].data = ;
}
cache.on(cb,cbName,url);
}
cache.on = function(cb,cbName,url){
if(cache[cbName].state == "loaded"){
cb(cache[cbName].data)
}else if(cache[cbName].state == "loading"){
cache[cbName].cbs.push(cb)
}else if(cache[cbName].state == "init"){
cache[cbName].cbs.push(cb);
cache[cbName].state = "loading";
cache.fetch(cb,cbName,url);
}
}
cache.broadcast = function(cbName){
cache[cbName].cbs.forEach(function(cb){
cb(cache[cbName].data)
});
}
cache.checkLoaded = function(cbName){
if(cache[cbName].data[0]){
cache[cbName].state = "loaded";
cache.broadcast(cbName);
}
}
cache.fetch = function(cb,cbName,url){
ls.loadScript({
url: url,
charset: "utf-8",
handleError:function(func, args, context,errorObj){
console.log(_errlogText + context);
cache[cbName].data[0] = {};
cache.checkLoaded(cbName);
}
});
if(window.cbName) return;
window[cbName] = function(json){
cache[cbName].data[0] = json;
cache.checkLoaded(cbName);
}
}

exports.getData = function(cb,cbName,url){
cache.init(cb,cbName,url);
}

})

完美解決問題,每個回調都不會遺漏或者被覆蓋……

擴展思路

該模塊可通用於處理一個頁面內同一個請求的情況。還可以擴展到處理一些需要2個請求以上完成才執行某個回調的情況。類似於Promose的情況。這個時候可以規定,每個data[0]裝的是固定的對應介面的數據,data[2]對應另一個,一次類推。不過這樣就要遍歷到每一項都為true的時候才執行回調。而且對應關係比較容易混亂,再擴展就不如直接用Promise來處理了。。。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

mysql主從複製原理探索
ASP.NET Core MVC 控制器創建與依賴注入
官方Tomcat鏡像Dockerfile分析及鏡像使用
基於多線程方式的串列通信介面數據接收案例

TAG:達人科技 |

您可能感興趣

PUBG常見問題及解決方法總匯 PUBG無法打開解決方法
重複頁面的SEO優化有什麼解決辦法
SAT寫作 I 學生常見問題&解決方案
戀與製作人只屬於你副本BUG怎麼回事?只屬於你副本活動BUG解決方法
為您解決綁定問題
重新定義拔罐療法,「NOSSA」給出時尚便捷的智能解決方案
美國立法者要求Uber及Lyft等公司解釋如何解決性侵犯問題
PCB設計的核心問題解決方案
基礎定乾坤,KBT幫你解決實戰痛點!
開機後USB沒反應的解決方案
HTC重點關注移動VR領域 望通過整體解決方案打開市場
IBM將推出基於Wason的 「認知解決方案」服務
停止更新BIOS!英特爾公布PC重啟BUG解決方案
訴訟案解決後 Uber尋求與Waymo達成合作
Django 解決跨域請求問題
社論:知識產權保護重在解決「雙低」
AdaSky攜手意法半導體為自動駕駛帶來高解析度紅外熱像解決方案
「互聯網+」背景下企業想轉型?你需要KPPW解決方案
各取所需?VIVO能徹底解決用戶痛點要求
絕地求生Steam更新時錯誤解決方法