JavaScript的執行流程是分爲"同步"與"異步"javascript
傳統的異步操做會在操做完成以後,使用回調函數傳回結果,而回調函數中則包含了後續的工做。這也是形成異步編程困難的主要緣由:css
咱們一直習慣於「線性」地編寫代碼邏輯,可是大量異步操做所帶來的回調函數,會把咱們的算法分解地支離破碎。html
動畫爲例,下一個動畫要等上一個執行完畢才能夠繼續,流程就會寫到回調裏面前端
//執行多個動畫 $('ele1').animate({ opacity: '.5' }, 4000, function() { $('ele2').animate({ width: '100px' }, 2000, function() { $('ele3').animate({ height: '0' }, 2000); }); });
上面的代碼編程邏輯也是正確的,可是針對這樣的異步嵌套的回調邏輯,當咱們的嵌套越多,代碼結構層級會變得愈來愈深。首先是閱讀上會變得困難,其次是強耦合,接口變得很差擴展。咱們須要一種模式來解決這種問題,這就是Promises所要作的事情。java
爲了讓前端們從回調的地獄中回到天堂, jQuery 也引入了 Promise 的概念。 Promise 是一種令代碼異步行爲更加優雅的抽象,有了它,咱們就能夠像寫同步代碼同樣去寫異步代碼。這個東西看起來很複雜,實際上咱們只要抓住核心的使用就能夠了。jquery
觀察下邊代碼:算法
經過$.Deferred處理過的代碼,很明顯沒有了回調的嵌套,雖然代碼量看起來多了點,可是實際上,每個代碼執行部分都被封裝了起來,只留了Deferred的接口處理了,等因而咱們把執行的流程控制交給了Deferred,這樣的好處就是咱們在寫嵌套函數的時候,能夠用deferred提供的管道風格編寫同步代碼了編程
dtd.then(function() { //操做1 }).then(function() { //操做2 }).then(function() { //操做3 })
這裏要了解3個步驟api
var dtd = $.Deferred(); //建立 dtd.resolve(); //成功 dtd.then() //執行回調
具體的咱們能夠參考下jQuery的Deferred部分的API說明,點擊此處異步
舉例
1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 6 <title>異步編程處理</title> 7 <style type="text/css"> 8 div { 9 background-color: yellow; 10 width: 200px; 11 height: 200px; 12 text-align: center; 13 border: 2px solid red; 14 margin: 3px; 15 font-size: 14px; 16 } 17 #block3,#block4{ 18 background-color: #CAE1FF; 19 } 20 button { 21 font-size: 14px; 22 } 23 </style> 24 <script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script> 25 </head> 26 27 <body> 28 <button>點擊測試回調處理</button> 29 <button>點擊測試$.Deferred處理</button> 30 </br> 31 </br> 32 <div id="block1">block1執行動畫</div> 33 <div id="block2">block2執行動畫</div> 34 <div id="block3">block3執行動畫</div> 35 <div id="block4">block4執行動畫</div> 36 37 <script type="text/javascript"> 38 // 回調處理 39 $('button:first').click(function() { 40 $("#block1").animate({ 41 width: "50%" 42 }, 2000, function() { // 嵌套回調 43 $("#block2").animate({ 44 width: "50%" 45 }, 2000); 46 }); 47 }); 48 49 // jQuery的Deferred處理 50 $('button:last').click(function() { 51 52 function animate1() { 53 var dtd = $.Deferred(); // 生成Deferred對象 54 $("#block3").animate({ 55 width: "50%" 56 }, 2000, function() { 57 dtd.resolve(); // 改變Deferred對象的執行狀態 58 }); 59 return dtd; 60 } 61 62 function animate2() { 63 var dtd = $.Deferred(); // 生成Deferred對象 64 $("#block4").animate({ 65 width: "50%" 66 }, 2000, function() { 67 dtd.resolve(); // 改變Deferred對象的執行狀態 68 }); 69 return dtd; 70 } 71 72 var anim = animate1(); 73 74 anim.then(function() { 75 $("#block3").text('block3動畫動畫直接結束'); 76 return animate2(); 77 }).then(function() { 78 $("#block4").text('block4動畫動畫直接結束'); 79 }); 80 81 }); 82 83 84 </script> 85 </body> 86 87 </html>