JavaScript当前有众多实现异步编程的方式,最为耀眼的就是ECMAScript 6规范中的Promise对象,在ES6还没发布的时候一般都是用jquery提供的deferred对象,在《jquery Deferred对象 延迟对象》在有介绍,其实jquery中提供的队列函数也可以简单实现回调的功能《jQuery队列函数同步执行queue()、dequeue()、clearQueue()和.delay()》。在不久前介绍过另一个异步编程插件《js异步模块以及回调–async.js》。
不管jquery的$.Deferred()和async.js他们都是解决了回调的问题,现在介绍另一款插件jsDeferred.js,其实它的思路和现在ES6添加的Promise对象思路是相似的,因为Promise/A+规范的制定基本上是奠定在jsDeferred上。
官网:https://cho45.stfuawsc.com/jsdeferred/
下面来介绍jsDeferred.js使用
官网有几个版本,其中有一个是基于jquery下扩展的,如果你经常使用jquery的话推荐使用jquery版本的
jsdeferred.jquery下载:jsdeferred.jquery
目前测试兼容IE7以上浏览器(IE6没测试)
如何调用
<script type="text/javascript" src="jsdeferred.js"></script> <script> 方式一:(个人喜欢这种方式) Deferred.define(); next(function () { alert("Hello!"); }). next(function () { alert("World!"); }); 方式二: Deferred.next(function () { alert("Hello!"); }). next(function () { alert("World!"); }); 方式三: var d = new Deferred(); d.next(function () { document.title=1; }). next(function () { document.title=2; }); d.call(); </script> 自己选喜欢的方式用吧
以后讲解案例就使用第一种方式说明
next()队列执行,类似回调作用
以往的写法内置回调嵌套 http.get("/foo.json", function (dataOfFoo) { http.get("/bar.json", function (dataOfBar) { http.get("/baz.json", function (dataOfBaz) { alert([dataOfFoo, dataOfBar, dataOfBaz]); }); }); }); next(function () { return http.get("/foo.json").next(function (data) { results.push(data); }); }). next(function () { return http.get("/baz.json").next(function (data) { results.push(data); }); }). next(function () { return http.get("/baz.json").next(function (data) { results.push(data); }); }). next(function () { alert(results); }); //next写法至少比第一种写法清晰多了
数据传递
next(function(){ alert(1); return [1,2] //只有reture才能把数据传递给下一个函数 }). next(function(data){ console.log(data); //这里data就是获取到上一步return出来的数据[1,2] });
parallel() 合并回调
parallel(fn)、parallel([])、parallel({}) //支持3中格式
parallel( function(){ return 1; }, function(){ return 2; }, function(){ return 3; } ).next(function(data){ console.log(data); //[1,2,3] }); ----------------- parallel([ function(){ return 1; }, function(){ return 2; }, function(){ return 3; } ]).next(function(data){ console.log(data); //[1,2,3] }); -------------------- parallel({ foo: next(function () { return 1; }), bar: next(function () { return 2; }) }).next(function (values) { console.log(values);// => Object { foo=1, bar=2 } });
Error 出错回调
我们写逻辑代码在进行判断时候如果满足条件就继续执行,如果不满足条件或者出错就执行错误的回调
next(function () { console.log(0); }). next(function () { console.log(1); throw {err:'错了'}; //抛出错误 }). next(function () { console.log(2); //这步不会执行 }). error(function (e) { console.log(e); //{err:'错了'} //处理错误的回调 }). next(function () { //继续执行 console.log(3); });
wait()时间延迟加载
next(function () { console.log(0); return wait(5); //5秒后才继续执行下一步 }). next(function () { console.log(1); })
嵌套
next(function () { alert(1); //第一步 return next(function () { alert(2); //第二步 }). next(function () { alert(3); //第三步 }); }). next(function () { alert(4); //第四步 }); 如果没有 return next(function () { alert(1); //第一步 next(function () { alert(2); //第三步 }). next(function () { alert(3); //第四步 }); }). next(function () { alert(4); //第二步 });
loop()循环 类似for循环
loop(1000, function (n) { //n索引从0开始 // heavy process });
call() //可以理解为一个jsDeferred内置提供的执行函数吧!,直接上案例不太好说明
next(function () { function pow (x, n) { //定义了pow函数但是没执行 return x+n; } return call(pow, 2, 10); // (要执行的函数,带入的参数1,带入的参数2) }). next(function (n) { console.log(n); //12 }); call(function (text) { console.log(text);//=> linkFly }, 'linkFly'); console.log('hello,world!');// => 先输出
判断某实例化的对象是否为jsDeferred内置的
var obj =new wo(); Deferred.define(); console.log(Deferred.isDeferred(obj));//=> false console.log(Deferred.isDeferred(wait(2)));//=> true
还有更多方法可以参考官网或者以下网站