异步编程的处理

JavaScript的执行流程是分为"同步"与"异步"

传统的异步操作会在操作完成之后,使用回调函数传回结果,而回调函数中则包含了后续的工作。这也是造成异步编程困难的主要原因:

   我们一直习惯于“线性”地编写代码逻辑,但是大量异步操作所带来的回调函数,会把我们的算法分解地支离破碎。

嵌套式回调

动画为例,下一个动画要等上一个执行完毕才可以继续,流程就会写到回调里面

//执行多个动画
$('ele1').animate({
    opacity: '.5'
}, 4000, function() {
    $('ele2').animate({
         '100px'
    }, 2000, function() {
        $('ele3').animate({
            height: '0'
        }, 2000);
    });
});

上面的代码编程逻辑也是正确的,但是针对这样的异步嵌套的回调逻辑,当我们的嵌套越多,代码结构层级会变得越来越深。首先是阅读上会变得困难,其次是强耦合,接口变得不好扩展。我们需要一种模式来解决这种问题,这就是Promises所要做的事情。

为了让前端们从回调的地狱中回到天堂, 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说明,点击此处

举例

 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              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              "50%"
42         }, 2000, function() {  // 嵌套回调
43             $("#block2").animate({
44                  "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                  "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                  "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>
View Code
原文地址:https://www.cnblogs.com/guorange/p/6685846.html