一、理解任务队列
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>