Deferred 实现异步编程

JavaScript 的执行流程分为"同步"与"异步"。传统的异步操作会在操作完成之后,使用回调函数传回结果,而回调函数中则包含了后续的工作。我们一直习惯于“线性”地编写代码逻辑,但是大量异步操作所带来的回调函数,会把我们的算法分解地支离破碎。


以动画为例,下一个动画要等上一个执行完毕才可以继续,流程就会写到回调函数里面
// 执行多个动画
$('ele1').animate({opacity:'0.5'},4000,function(){
    $('ele2').animate({width:'100px'},2000,function(){
        $('ele3').animate({height:'0'},2000);
    });
});

上面的代码编程逻辑也是正确的,但是针对这样的异步嵌套的回调逻辑,当我们的嵌套越多,代码结构层级会变得越来越深。首先

是阅读上会变得困难,其次是强耦合,接口变得不好扩展。


jQuery 引入了 Deferred 的概念。 Deferred 是一种令代码异步行为更加优雅的抽象,有了它,我们就可以像写同步代码一样去写

异步代码。这个东西看起来很复杂,实际上我们只要抓住核心的使用就可以了。Deferred对象就是jQuery的回调函数解决方案。在

英语中,defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。


通过 $.Deferred 处理过的代码,很明显没有了回调的嵌套,虽然代码量看起来多了点,但是实际上,每一个代码执行部分都被封装

了起来,只留了Deferred的接口处理,等于是我们把执行的流程控制交给了Deferred,这样的好处就是我们在写嵌套函数的时候,

可以用deferred提供的管道风格编写同步代码了。


代码示例:

function animate1() {
    var dtd = $.Deferred(); // 创建Deferred对象
    $("#block1").animate({width:400px},2000,function() {
        dtd.resolve(); // 改变Deferred对象的执行状态为“已完成”
    });
    return dtd;
}
function animate2() {
    var dtd = $.Deferred(); // 创建Deferred对象
    $("#block2").animate({width:"50%"}, 2000, function() {
        dtd.resolve(); // 改变Deferred对象的执行状态为“已完成”
    });
    return dtd;
}
var anim = animate1();
anim.then(function() {
    $("#block1").text('block1动画结束');
    return animate2();
}).then(function() {
    $("#block2").text('block2动画结束');
});


你可能感兴趣的:(JavaScript)