框架基礎:ajax設計方案(二)---集成輪詢技術 框架基礎:ajax設計方案(二)---集成輪詢技術

框架基礎:ajax設計方案(二)---集成輪詢技術

上一篇文章介紹了ajax技術核心方法,和跨域的問題(只要後臺支持跨域默認post就能夠),這篇文章講解一下使用ajax實現的輪詢技術,至於iframe,SSE服務器單向推送,以及webSocket雙工通道暫時不涉及javascript

一些概念:html

  短輪詢:瀏覽器經過循環或者setTimeout方法,每隔一段時間日後臺發送一次請求,無線循環前端

  長輪詢:不停的向後臺請求數據,可是後臺若是檢測不到數據變更,就會將這個請求掛掉。若是檢測到數據變更,就會響應這個請求變更數據java

區別概念:git

  長鏈接:在進行http數據傳輸的時候,在數據傳輸層一直開着一個TCP通道,全部請求資源文件都是經過複用這個通道去請求數據,有超時時間github

  短鏈接:若是http進行的短鏈接,即每次瀏覽器發送請求,都會建立TCP通道,而後傳輸完成了再進行銷燬,重複操做,消耗很大web

 

主要區別:ajax

  1. http的長短輪詢,經過代碼層,向後臺請求數據。
  2. Http的長短鏈接,實際上就是TCP協議傳輸層是否複用一個TCP協議。

 

主要業務方面:及時性比較高的應用(web端聊天系統),或者須要後臺等待響應的應用(好比付款,等待完成響應)。後端

關鍵代碼:跨域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
     * 長輪詢的實現
     *   a. 業務上只須要獲得服務器一次響應的輪詢
     *   b. 業務上須要無限次獲得服務器響應的輪詢
     *
     *   param: url   請求接口地址
     *          data  請求參數
     *          successEvent    成功事件處理
     *          isAll           是否一直請求(例如,等待付款完成業務,只須要請求一次)
     *          timeout         ajax超時時間
     *          timeFrequency   每隔多少時間發送一次請求
     *          error           錯誤事件
     *          timeout         超時處理
     * */
    longPolling: function (url,data,successEvent,isAll,timeout,timeFrequency,errorEvent,timeoutEvent){
        var  ajaxParam ={
            time:timeout,
            type: "post" ,
            url:url,
            data:data,
            async: false ,
            success: function (date){
                successEvent(data);
                var  timer = setTimeout(
                    function (){
                        tempObj.longPolling(url,data,successEvent,isAll,error,timeoutEvent);
                    },timeFrequency);
                //業務需求判斷,是否只須要獲得一次結果
                if  (!isAll) clearTimeout(timer);
            },
            //若是走了error說明該接口有問題,不必繼續下去了
            error:errorEvent,
            timeout: function (){
                timeoutEvent();
                setTimeout( function (){
                    tempObj.longPolling(url,data,successEvent,isAll,error,timeoutEvent)
                },timeFrequency);
            }
        };
        ajax.common(ajaxParam);
    }

 

考慮到業務需求,集成了一次isAll參數有2個意義

  1. 聊天系統會要一直需求輪詢,不間斷的向後臺使用數據,因此isAll = true
  2. 等待付款業務只須要獲得後臺一次響應是否支付成功,因此isAll = false

 

稍微說起一下遇到的一些問題:

問題:

1
2
3
4
success: function (date){
      successEvent(data);     //此處使用遞歸,不停遞歸本身
      tempObj.longPolling(url,data,successEvent,isAll,error,timeoutEvent);
},       

瀏覽器報錯:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Uncaught RangeError: Maximum call stack size exceeded.
     at Object.common (ajax-1.2.js:202)
     at Object.longPolling (ajax-1.2.js:280)
     at Object.success (ajax-1.2.js:266)
     at XMLHttpRequest.xhr.onload (ajax-1.2.js:160)
     at Object.common (ajax-1.2.js:202)
     at Object.longPolling (ajax-1.2.js:280)
     at Object.success (ajax-1.2.js:266)
     at XMLHttpRequest.xhr.onload (ajax-1.2.js:160)
     at Object.common (ajax-1.2.js:202)
     at Object.longPolling (ajax-1.2.js:280)
common @ ajax-1.2.js:202
longPolling @ ajax-1.2.js:280
success @ ajax-1.2.js:266
xhr.onload @ ajax-1.2.js:160
(anonymous) @ index.html:42
(anonymous) @ index.html:43
 
ajax-1.2.js:202 Uncaught RangeError: Maximum call stack size exceeded.
     at Object.common (ajax-1.2.js:202)
     at Object.longPolling (ajax-1.2.js:280)
     at Object.success (ajax-1.2.js:266)
     at XMLHttpRequest.xhr.onload (ajax-1.2.js:160)
     at Object.common (ajax-1.2.js:202)
     at Object.longPolling (ajax-1.2.js:280)
     at Object.success (ajax-1.2.js:266)
     at XMLHttpRequest.xhr.onload (ajax-1.2.js:160)
     at Object.common (ajax-1.2.js:202)
     at Object.longPolling (ajax-1.2.js:280)

 

英文解釋:

超出最大調用堆棧大小。

問題緣由:

遞歸調用過多致使的棧溢出問題說明

問題解釋:

函數調用的參數是經過棧空間來傳遞的,在調用過程當中會佔用線程的棧資源。而遞歸調用,只有走到最後的結束點後函數才能依次退出,而未到達最後的結束點以前,佔用的棧空間一直沒有釋放,若是遞歸調用次數過多,就可能致使佔用的棧資源超過線程的最大值,從而致使棧溢出,致使程序的異常退出。js能夠調用自身,這裏不停的調用longPolling方法,在方法裏面不停的調用本身,致使GC(垃圾回收)一直不釋放,愈來愈大,致使資源超過最大上限,直接崩潰。而後級聯一層一層的拋出崩潰信息

解決方案:

使用settimeout解決該問題

方案解釋:

由於Javascript是單線程的,有個排隊的處理隊列,因此settimeout至關於有一個計時器,不停的向這個隊列每隔一段時間塞進一個處理事件。由於這樣,至關於longPolling方法每次都走完了,GC就將該方法的資源釋放了,而後再執行,再釋放。

 

代碼已集成github:https://github.com/GerryIsWarrior/ajax     點顆星星是我最大的鼓勵,下一步研究ajax的上傳文件技術(H5的)

 

PS:對於輪詢這個技術,雖然平時用的少,可是在一些特殊的業務場景能發揮很大的做用。在瀏覽器,沒有完徹底全支持H5的境況下,這個仍是要考慮的。畢竟H5的那些webSocket仍是須要H5兼容的。並且,研究這一塊,對原聲js,和計算機的一些底層技術仍是頗有幫助的,像堆棧溢出,不單單是前端,後端也會遇到。這樣的話,本身底層更夯實,對於之後上層的發展也會有更好的增加。

 

 

【轉發自http://www.cnblogs.com/GerryOfZhong/p/6135288.html】

相關文章
相關標籤/搜索