1. setTimeout
console.log('1 start') //1. 打印 script start
setTimeout(function(){
console.log('settimeout') // 4. 打印 settimeout
}) // 2. 调用 setTimeout 函数,并定义其完成后执行的回调函数
console.log('2 end') //3. 打印 script start
// 输出顺序:
1 start->
2 end->
settimeout
2. Promise
Promise本身是同步的立即执行函数, 当在executor中执行resolve或者reject的时候, 此时是异步操作, 会先执行then/catch等,当主栈完成后,才会去调用resolve/reject中存放的方法执行,打印p的时候,是打印的返回结果,一个Promise实例。
console.log('1 start')
let promise1 = new Promise(function (resolve) {
console.log('promise1')
resolve()
console.log('promise1 end')
}).then(function () {
console.log('promise2')
})
setTimeout(function(){
console.log('settimeout')
})
console.log('2 end')
// 输出顺序:
1 start->
promise1->
promise1 end->
2 end->
promise2->
settimeout
当JS主线程执行到Promise对象时,
-
promise1.then() 的回调就是一个 task
-
promise1 是 resolved或rejected: 那这个 task 就会放入当前事件循环回合的 microtask queue
-
promise1 是 pending: 这个 task 就会放入 事件循环的未来的某个(可能下一个)回合的 microtask queue 中
-
setTimeout 的回调也是个 task ,它会被放入 macrotask queue 即使是 0ms 的情况
3. async/await
async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
// 输出顺序:
script start->
async1 start->
async2->
script end->
async1 end
async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再执行函数体内后面的语句。可以理解为,是让出了线程,跳出了 async 函数体。
4.Event Loop:
setTimeout是一个macro任务
promise、和await后续为micro任务
所以在执行顺序上会先进行同步代码,再者Promise、Async/Await,最后setTimeout。
5.Promise、Async/Await差异
promise是resolve为异步方法,将放入微任务队里里执行,但是resolve前后的正常代码为同步代码;Async/Await会返回一个promise,await 的顺序是从右往左的,也就是说await 右边的方法也优先执行同步代码,再让出线程,进入微任务队列,await下面的代码可以理解为promise then里面的代码。
async function async1() {
console.log( 'async1 start' )
await async2()
console.log( 'async1 end' )
}
async function async2() {
console.log( 'async2' )
}
console.log( 'script start' )
setTimeout( function () {
console.log( 'setTimeout' )
}, 0 )
async1();
new Promise( function ( resolve ) {
console.log( 'promise1' )
resolve();
} ).then( function () {
console.log( 'promise2' )
} )
console.log( 'script end' )
结果: