JavaScript的执行流程是分为"同步"与"异步"
圣诞主题在技术上用了大量的异步机制,比如css3的transition、animation、定时器以及事件等等。异步会带来一个很大的问题:大量的“嵌套回调”
setTimeout(function(){ //任务一 setTimeout(function(){ //任务二 },1000) },1000)
上面最简单的定时器异步代码,任务二的执行,必须等待任务一完成。其中最明显的问题就是如果一直异步调用,代码嵌套非常严重。这个代码本身是没错的,逻辑也是正常的,但是从维护的角度来说,同步的代码更符合人的线性逻辑思维
为了改成异步编程的流程问题, jQuery 也引入了 Promise 的概念。 Promise 是一种令代码异步行为更加优雅的抽象,有了它,我们就可以像写同步代码一样去写异步代码。这个东东看起来很复杂,实际上我们只要抓住核心的使用就可以
观察右边代码:
通过$.Deferred处理过的代码,很明显没有了回调的嵌套,虽然代码量看起来多了点,但是实际上,每一个代码执行部分都被封装了起来,只留了Deferred的接口处理了,等于是我们把执行的流程控制交给了Deferred,这样的好处就是我们在写嵌套函数的时候,可以用deferred提供的管道风格编写同步代码了
dtd.then(function() { //操作1 }).then(function() { //操作2 }).then(function() { //操作3 })
这里要了解3个步骤
var dtd = $.Deferred(); //创建
dtd.resolve(); //成功
dtd.then() //执行回调
具体的我们可以参考下jQuery的Deferred部分的API说明,点击此处
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title>圣诞主题</title> <style type="text/css"> </style> <script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script> </head> <body> 显示结果:<p class="container"></p> <button>嵌套回调异步</button> <button>$.Deferred异步</button> <script type="text/javascript"> $("button:first").on("click", function() { //模拟异步A function A(callback) { setTimeout(function() { callback(1) }, 500) } //模拟异步A function B(callback, value) { setTimeout(function() { callback(value + 2) }, 1000) } //A执行完毕后,在执行B A(function(data1) { B(function(data2) { $(".container").html("嵌套异步:" + data2) }, data1) }) }) $("button:last").on("click", function() { // $.Deferred改造 // // //模拟异步C function C() { var dtd = $.Deferred(); //创建 setTimeout(function() { dtd.resolve(3) }, 500) return dtd; } //模拟异步D function D(value) { var dtd = $.Deferred(); //创建 setTimeout(function() { dtd.resolve(value + 4) }, 500) return dtd; } //模拟异步E function E(value) { var dtd = $.Deferred(); //创建 setTimeout(function() { dtd.resolve(value + 5) }, 1000) return dtd; } C() .then(function(data) { return D(data) }) .then(function(data) { return E(data) }) .then(function(data) { $(".container").html("Deferred异步处理:" + data) }) }) </script> </body> </html>