首页 > 技术文章 > 理解任务队列,异步编程

wszzj 2019-12-07 17:50 原文

一、理解任务队列

JavaScript 引擎同一时刻只能执行一个代码块,每当一段代码准备执行时,都会被添加到任务队列中。  当 JavaScript 引擎执行完一段代码后,会接着执行任务队列中的下一个任务。
 1  <script>
 2 
 3 
 4         /* 
 5         
 6             JavaScript 引擎同一时刻只能执行一个代码块,每当一段代码准备执行时,都会被添加到任务队列中。
 7             当 JavaScript 引擎执行完一段代码后,会接着执行任务队列中的下一个任务。
 8         
 9          */
10 
11         function foo() {             
12             console.log('foo-start')      //第一步
13             function bar() {             
14                 console.log('bar')
15             }
16             console.log('测试')          //第二步
17             bar()                        //第三步,调用 bar()
18             console.log('foo-end')       //第四步
19         }
20 
21         foo();
22 
23     </script>

 

 

图中示例1,当调用foo()函数时,function foo()    就会被送到任务队列中,当函数执行完成之后 function foo()  就会从任务队列中弹出去

图中示例2,当调用foo()函数时,function foo()    进入到任务队列中,接着往下走,遇到 bar()   之后  function bar()    进入到任务队列中  ,函数执行完成后,先执行   function bar()    再执行 function foo()      (任务队列相当于栈队列)

 

 1.2 之前所学的异步编程

 1 <body>
 2     <script>
 3 
 4         
 5 
 6         // 异步编程的方式:事件回调、回调函数、Promise
 7         
 8         // 事件回调
 9         // const xhr = new XMLHttpRequest();
10         // xhr.onreadystatechange = function () {
11         //     if (xhr.readyState === 4) {
12         //         // 这里代码只有请求完成之后才会执行
13         //     }
14         // };
15 
16         // 回调函数
17         function foo(fun) {
18             setTimeout(() => {
19                 // foo() 函数的任务完成之后调用传入的 bar 函数,也就是形参 fun
20                 console.log('foo 任务完成');
21                 fun();
22             }, 2000)
23         }
24 
25         function bar () {
26             console.log('bar 任务完成')
27         }
28 
29         // 把函数 bar() 作为 foo() 函数的参数传入
30         foo(bar)
31         
32     </script>
33 </body>

1.3 异步编程-Promise对象

 

 1 <body>
 2     <script>
 3 
 4         // Promise 对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)
 5 
 6         const promise = new Promise(function (resolve, reject) {
 7 
 8             // 任务执行成功时,调用 resolve() 函数
 9 
10             // 任务执行失败时,调用 reject() 函数
11 
12             if (false) {
13                 resolve('第一个任务执行完成之后得到的结果')
14             } else {
15                 reject('告诉第二个任务失败的原因')
16             }
17 
18         });
19 
20         // 1. 同时监听成功和失败时的回调
21         promise.then(function (value) {
22             // 当上一个任务执行成功时,会执行这里的代码,并将上一个任务得到结果传入该函数
23             console.log(value)
24         }, function (reason) {
25             // 当上一个任务执行失败时,会执行这里的代码,并将上一个任务失败的原因传入该函数
26             console.log(reason)
27         });
28 
29         // 2. 只监听成功时的回调
30         promise.then(function (value) {
31             // 当上一个任务执行成功时,会执行这里的代码,并将上一个任务得到结果传入该函数
32             console.log(value)
33         });
34 
35         // 3. 只监听失败时的回调
36         promise.then(null, function (reason) {
37             // 当上一个任务执行失败时,会执行这里的代码,并将上一个任务失败的原因传入该函数
38             console.log(reason)
39         });
40 
41         // 4. catch() 方法相当于只传入失败处理函数的 then() 方法。上面的代码等于下面的写法:
42         promise.catch(function (reason) {
43             console.log(reason)
44         })
45 
46     </script>
47 </body>

 

 

 

推荐阅读