1.如何实现一个轮询?
function getMessage(url,callback){ var XHR=new XMLHttpRequest(); XHR.open('get',url,true); XHR.onreadystatechange=function(){ if(XHR.readyState==4){ //do something if(callback){ callback(XHR.responseText); } } }; XHR.send();
setTimeout(function(){getMessage(url,callback),2000);//采用递归的方式达成轮询效果 } setTimeout(function(){getMessage(url,callback),2000);//采用递归的方式达成轮询效果
缺点:对于即时发送即时得到结果的短轮询,这是一种不错的选择,但是如果服务器不会立即响应请求,那就会产生不好的效果,是请求堆积,给服务器增压。
2.所以长轮询应运而生
function getMessage(url,callback){ var xhr=new XHRHttpRequest(); xhr.open('get',url,true); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ //do something if(callback){ callback(); } xhr.open('get',url,true);setTimeout(function(){getMessage(url,callback);},2000);
xhr.send();//这里完成了循环过程
} }; xhr.send(); }
这样的轮询方式解决了短轮询那样无休止的发送请求,而是改为只要服务器搭理我并给我返回数据,我才会继续轮询。
3.JSONP或callback轮询
无论是长轮询或段轮询都不能跨域进行数据请求,所以JSONP轮询应运而生。
function getMessage(url,callback){ var oScript=document.createElement('script'); oScript.src=url+'?callback=getMessage.callback'; getMessage.callback=function(data){ callback(data); getMessage(url,callback);//递归调用完成轮询过程 }
document.getElementsByTagName('head')[0].appendChild(oScript); }
声明:这些轮询技术不可避免的问题就是增加服务器CPU的负担,虽然Comet服务器会优化HTTP/线程/进程,但是不会优化套接字的规模数,这些都会给服务器造成不可预知的问题,所以还要使用替代技术做一些优化,从而避免套接字的检查。