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
还有更多方法可以参考官网或者以下网站