框架基础: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】

相关文章
相关标签/搜索