- 浏览: 307101 次
- 性别:
- 来自: 河南郑州
文章分类
最新评论
-
sillydong:
https://github.com/sillydong/CZ ...
PHP 框架 Yaf 学习笔记----默认行为 -
achun:
jocce 写道var data1={};里面放的是json数 ...
jCT 嵌入模板简化方案 -
jocce:
var data1={};里面放的是json数据吗?为什么我用 ...
jCT 嵌入模板简化方案 -
achun:
randomnany 写道hi:你说的那个所谓的bug不是bu ...
PHP 框架 Yaf 学习笔记----默认行为 -
randomnany:
hi:你说的那个所谓的bug不是bug~yaf默认的就是读取 ...
PHP 框架 Yaf 学习笔记----默认行为
如果在一个函数中,我们需要的数据是要从ajax获取。如果用ajax同步 的方法,浏览器会挂起,这是一个很讨厌的事情。
而ajax异步 在浏览器中的实现是立即返回的,而我们要的数据还没有被获取。
那用ajax异步 的方法怎么做才能达到我们的目的呢?让我们一步步实现伪同步.
先给个简单的方法:
function foo(data){ if(undefined==data) return ajaxQueue({...},{callback:arguments.callee}); ......someting...... }
也就是说:
函数foo内部有ajax异步(ajaxQueue就是入口)的请求,而且ajax后的结果对foo的内部(someting)执行有影响,因此需要在foo内部进行判断是否ajax异步请求已经完成 ,或者说调用者是否是ajax异步请求 .
上面代码中用了一个简单的判断
if(undefined==data)
而
{callback:arguments.callee}
就是告诉ajaxQueue取到数据后,再回调foo了.
不过这个方法有问题,也就是借用了foo 函数的参数值,在某些场合也许就不适用了。因此这个方法是有问题的,ajaxQueue的实现也就失去了讨论的意义。
首先让我们完善上面的方法:注意闭包的用法(也不知道会不会造成内存泄漏)
function ajaxCallback(queue,args){ var func=arguments.callee.caller; var length=queue.length; for (var i=0;i<queue.length;i++) (function(){ var o=queue[i]; var _old = o.complete; o.complete = function(){ if ( _old ) _old.apply( this, arguments ); length--; if (0==length) { func.apply(ajaxCallback,args); } }; jQuery.ajax(o); })(); }
调用:
function foo(ddd){ if(this!==ajaxCallback){ return ajaxCallback([ {url:'/1.txt',complete:function(){alert(1);}}, {url:'/1.txt',complete:function(){alert(2);}}], arguments); } alert(arguments.length); alert(ddd) } foo(3);
这里面还有一个问题,就是虽然没有借用参数,但是借用了this(我是不是绕的弯弯太多了,直奔正解不就行了,其实这是我解决这个时候的思路,自己记录一下).对OO的编程可就有产生了新的麻烦。
改一下:
function ajaxCallback(queue,args){ var func=arguments.callee.caller; var length=queue.length; for (var i=0;i<queue.length;i++){ (function (){ var o=queue[i]; var _old = o.complete; o.complete = function(){ if ( _old ) _old.apply( this, arguments); length--; if (0==length) { Callback(func,args[0],args[1]); } }; jQuery.ajax(o); })(); } } function Callback(func,self,args){ func.apply(self,args); }
测试:
function foo(ddd){ if(arguments.callee.caller!=Callback){ return ajaxCallback([ {url:'/1.txt',complete:function(){alert(1);}}, {url:'/1.txt',complete:function(){alert(2);}}], [this,arguments]); } alert(ddd); alert(this); } foo(3); var f={}; f.foo=foo; f.foo(3);
这回好了。不占参数,this也得到了正确(其实是调用的时候主动传过去的)传递.
ajax 伪同步实现.
备注 :您需要明白的是,我这里说的同步指的是调用ajax的函数实现了伪阻塞,关于多ajax请求伪同步的方法有队列法,比如jQuery的插件ajaxQueue ,从某种意义上说我的这个方法也可以实现,不过既然人家工作的很好,就不费这个力气了.
暂时思路只能到这里,进一步要靠实践了.
更新.感觉函数的名字起的不好,改了下,而且增加了不需要回调的判断:
//多ajax请求队列,支持完结回调 function ajaxQueue(queue,thiss,argss,other){ if (arguments.length<1) return false; if (!argss) argss=[]; var args=[]; for (var i=0;i<argss.length ;i++ ) args.push(argss[i]); if (other) for (var i=0;i<other.length ;i++) args.push(other[i]); var func=arguments.callee.caller; (function (a,func,thiss,args){ var o=a.shift(); //增加了判断是否要回调 if (!o) return thiss?thisCallback(func,thiss,args):false; var self=arguments.callee; var _old = o.complete; o.complete = function(){ if ( _old ) _old.apply( this, arguments); self(a,func,thiss,args); }; jQuery.ajax(o); })(queue,func,thiss,args); return false; } //回调函数,保持原来的this指针 function thisCallback(func,thiss,args){ if (func.constructor == Function) func.apply(thiss,args); return false; }
评论
<div class="quote_div">看不懂怎样使用,能否给一些使用的演示代码</div>
<p> </p>
<p>晕呀,那个打包工具的代码没有了,链接当然也无效了。</p>
<p>其实这就是一个ajax获取数据的工具,我的应用中需要多次向后台进行ajax请求,而这些请求必须是按次序进行的。</p>
<p>举一个实际的例子吧</p>
<p>您如果看了我的博客的话,会发现<a href="http://achun.iteye.com/category/33268" target="_blank">jCT</a> 这个前台模板工具。对于模板来说有两部分</p>
<p>1.是模板文件</p>
<p>2.对应的数据</p>
<p>对于前台模板工具来说,这两部分要分别从后台获取的,如果采用ajax方法取这两个数据的时候,可以发出两个ajax请求,但是在任何一个请求完成以后就要判断另一个是否也完成了,这有些麻烦。</p>
<p>如果采用我上面说的为阻塞,也就是ajax队列的方法就不存在这个问题,因为事实上每次只有一个ajax的请求被发出,队列中的请求是顺序执行的。</p>
<p> </p>
<p>比如有一个列表的模板文件 /template/list.html</p>
<p>而对应的后台数据请求是 /?getlist=99</p>
<p>处理这两个数据的对象是 </p>
<pre name="code" class="js">obj={
template:function(){},
listdata:function(){}
}</pre>
<p>那调用代码可以是这样</p>
<pre name="code" class="js">ajaxQueue('/template/list.html',obj,obj.template);
ajaxQueue('/?getlist=99',obj,obj,listdata);</pre>
<p>很明显当第2个请求完成的时候,模板已经正确处理过了,可以进行视图的表现了。</p>
<p>事实上我上面的例子根本就无法在我上面提供的函数中正确运行,不好意思,那是最初的想法和代码,现在的写法如下</p>
<pre name="code" class="js">function ajaxQueue(data,apply,cb,args,ask){
if(typeof apply=='string' && !confirm(apply)) return;
if(typeof cb=='string' && !confirm(cb)) return;
if(typeof args=='string' && !confirm(args)) return;
if(typeof ask=='string' && !confirm(ask)) return;//上面这些个判断都是用在缺少足够的参数,并且有提交提问的判断
if(typeof apply=='string') apply=false;
var url,dat,type,datatype;
if(typeof data=='string'){
url=data;
dat=null;
type='GET';
datatype='text';
}else{
url='/';
dat=$.toJSON(data);
type='POST';
datatype='json';
}
if (arguments.length)
ajaxQueue.Queue.push({
url:url,
data:dat,
userData:{
cb:apply===false?null:(typeof cb=='function'?cb:arguments.callee.caller),
apply:apply ||window,
args:(args instanceof Array)?args:(cb instanceof Array?cb:[])
},
type:type,
dataType:datatype,
error:function(xhr){
if(xhr.responseText=='')
alert('无效的请求.');
else
alert('服务器数据错误.')
setTimeout('ajaxQueue()',0);
},
success: function(json){
thisCallback(this.userData.cb,this.userData.apply,[json].concat(this.userData.args));
setTimeout('ajaxQueue()',0);
}
});
var o=ajaxQueue.Queue.shift();
if(o) jQuery.ajax(o);
}
ajaxQueue.Queue=[];
function thisCallback(func,apply,args){
if (typeof func=='function'){
if (!(args instanceof Array)) args=args==undefined?[]:[args];
func.apply(apply,args);
}
return false;
}</pre>
<p> </p>
<p>在上述写法中,ajax请求的数据data被自动的识别了。至于dat=$.toJSON(data) 的用法,参见我的另外一篇文章</p>
<h3 class="type_original" title="原创"><a href="http://achun.iteye.com/blog/200417">降低前后台业务逻辑上的耦合度,前后台细粒度数据通讯的方法</a></h3>
<p> </p>
<p> </p>
我正在写的nicEdit 打包器
用的就是这个方法+jCT做的,现在还没有做完,感兴趣可以看看,有实例参考也许会对你有启发.
源文件目录
http://ne.16lo.com/src/nicEditor/
achun.html就是jCT模板,
src/nicEditor/src 目录是nicEditor的源文件
_.php是入口文件,不允许浏览器访问,内容如下:
foreach ($AQ as $Q=>$P){ switch ($Q){ case 'entry': se_Msg(se_webPath(dirname(__FILE__))); break; } }
其实就是输出一个相对浏览器的entry URL,就是他了
{"entry":"/src/nicEditor"}
我的服务器目录是配置了只有src下的才能浏览,
使用FF+FireBug可以监视到整个实现.
<pre name='code' class='js'>//回调函数,保持原来的this指针
function thisCallback(func,thiss,args){
func.apply(thiss,args);
return false;
}
//把arguments分成argss,other两部分完全是为了调用方便.方便到哪里了你用了就明白了.
function ajaxQueue(queue,thiss,argss,other){
if (arguments.length<3) return false;
var args=[];
for (var i=0;i<argss.length ;i++ )
args.push(argss[i]);
if (other)
for (var i=0;i<other.length ;i++)
args.push(other[i]);
var func=arguments.callee.caller;
(function (a,func,thiss,args){
var o=a.shift();
if (!o) return thisCallback(func,thiss,args);
var self=arguments.callee;
var _old = o.complete;
o.complete = function(){
if ( _old ) _old.apply( this, arguments);
self(a,func,thiss,args);
};
jQuery.ajax(o);
})(queue,func,thiss,args);
return false;
}</pre>
<p> 调用的例子:动态执行服务器端的js</p>
<pre name='code' class='js'>//参数a是要动态请求的服务器端的js文件
function test(a){
if(arguments.callee.caller==thisCallback){
alert('ok');
return;
}
var queue=[];
for(var i=0;i<a.jslist.length;i++){
queue.push({url:a.jslist[i],success:function(js){
try{
window.eval(js);
}catch(ex){//错误处理代码,这个要看你的处理了
$('#error').append('<pre>Error:\n'+ex.message + '\n'+ (ex.lineNumber || ex.number)+'</pre>');
}
}});
}
ajaxQueue(queue,this,['ajaxQueue']);
return;
}</pre>
<p> 当然还可以设计出success出错后的中断队列的模式,暂时不写了,因为很容易,等我的应用有需求的时候再写吧.</p>
发表评论
-
请求社区帮助,写了个类似于 selectivizr 的工具BCCF
2012-05-16 18:00 1678写了个类似于 selectivizr 的工具,可是工作量太 ... -
遭遇 IE split 正则问题
2011-03-03 08:49 1944遭遇 IE split 正则问题 alert( ... -
JS/CC 解析生成器 by javascript
2010-12-10 00:02 1344用 javascript 做的解析生成器?没错。这是真的, ... -
MongoDB 我得到了WEB前后端数据通讯接口的思路
2010-12-04 12:21 2468自从进入WEB开发以来, ... -
再论在javascript中如何判断一个方法是new调用还是一般调用
2009-09-22 08:33 1356这本来是一个老讨论了 http://www.iteye.com ... -
简洁的 javascript 国际化翻译函数
2008-11-03 12:21 2101今天想到的这样的写法,感觉非常通用. 使用的时候可以把这个作 ... -
caller 仿冒,有浏览器兼容性问题!纯属探讨测试
2008-07-16 14:59 1605首先,我不知道这个方法能怎么应用,仅仅知道这是一种无副作用的方 ... -
JavaScript对象工厂实现(发现此方法有浏览器兼容性问题,无效了)
2008-07-13 01:03 1223这个工厂是不是和别人说的工厂模式不太一样呀!所以说是对象工厂。 ... -
无污染的 JavaScript 对象设计
2008-07-12 23:02 2430在使用JavaScript构建对象时,出于某种需求要使用pro ... -
Action By Class,利用Element 的class触发行为
2008-07-06 15:49 1412做Web应用,页面上的元素(Element),常常要进行一些特 ... -
测试,探讨jMixin模式
2008-07-05 18:49 1326修正后的Mixin function inMixin(){ ... -
善用arguments.callee.apply,让递归兼容Mixin,正确继承this
2008-07-01 09:42 3641javascript 中递归的使用也是常见的.比如遍历DOM树 ...
相关推荐
伪同步调用ajax(伪阻塞); 伪同步调用ajax(伪阻塞);
在进行网络编程时,常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式 同步/异步主要针对C端: 同步:c端发出一个功能调用时,在没有得到结果之前,c端死等结果 例如:普通B/S模式(同步)...
1、XmlHttpRequest对象的open方法允许程序员用一个ajax调用向服务器发送请求。 2、method表示请求类型。最常用的有get和post请求。如果不向服务器端发送数据,只是请求服务器端的数据,这个时候可以用get方法。...
很多公司使用另开线程池的方式进行异步调用来解决tomcat线程阻塞问题。但由于本系统中接口网络太不稳定,使用线程池也将导致线程池中的线程不断加大,不管使用怎样的线程池策略,最终要么线程池线程全部挂起,要么...
各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络相关,UDP 基于JAVA的UDP服务器模型源代码...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...
),对于同步方式的通信,这是很有效的,但是这样的方式对于异步通信会出现问题,因为没有了进程的堵塞,用户可能在上一次通信未完成时再次调用同一个xmlhttp实例,这样不等前一个调用的回调函数触发,前一次调用就...
在执行请求的时候阻塞浏览器。这是在保证数据的同步性比交互更重要的情况下的一种更好的方法。 var html = $.ajax({ url: "some.php", async: false }).responseText;向服务器发送xml文档数据。...
06 阻塞IO与非阻塞IO 07 select及触发方式 08 select监听多连接 09 select与epoll的实现区别 第36章 01 异步IO 02 selectors模块介绍 03 selectors模块应用 04 作业介绍 第37章 01 selctors实现文件上传与下载 ...
- 自动升级(本地记录版本,服务器js调用 参数 url、###version;忽略此版本。cookie。统计用户) ###ver2.0 debug `2014/3/2` ---- ####fix bug:(bug解决和程序优化) - 优化文件打开处理 - 文件&文件夹:含有%...
各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络相关,UDP 基于JAVA的UDP服务器模型源代码...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...
4、同步调用; 5、超时机制; 6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4...