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