10,异步:分析事件循环中函数执行顺序
2019-11-18 本文已影响0人
r8HZGEmq
//请写出输出内容
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');
/*
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
*/
任务队列机制+任务源task.png
主线程:任务栈、同步任务
事件触发线程:异步任务有了结果,在该队列中放置一个事件
主线程执行完后,便开始从任务队列取一个,放到可执行栈中。
浏览器中的执行机制:
(macro)task->渲染->(macro)task->渲染...
宏任务:scriptCode、setTimeout、setInterval、I/O、UI交互...
微任务,介于宏任务和渲染之前。当前任务执行完后,立即执行的任务。不用等待渲染,所以比setTimeout...更快。
也就是说,某一宏任务执行完后,该宏任务所产生的microTask会立刻执行。包括:
promise.then、process.nextTick
JS运行机制:
每次循环操作称为tick的核心步骤.png
最后我们分析题目前,预备一个小知识点:(也就是说,任务源归属到Promise。同源的微任务分配到同一个微栈。)
await async2();
console.log('async1 end');
等价于
Promise.resolve(async2()).then(() => {
console.log('async1 end')
})
接下来:按照上面准备的知识点,可以分析出执行结果
再看几个变形加深印象:
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
//async2做出如下更改:
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise3');
resolve();
}).then(function() {
console.log('promise4');
});
console.log('script end');
//---------
script start
async1 start
promise1
promise3
script end
promise2
async1 end
promise4
setTimeout
async function async1() {
console.log('async1 start');
await async2();
//更改如下:
setTimeout(function() {
console.log('setTimeout1')
},0)
}
async function async2() {
//更改如下:
setTimeout(function() {
console.log('setTimeout2')
},0)
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout3');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
//---------
script start
async1 start
promise1
script end
promise2
setTimeout3
setTimeout2
setTimeout1
async function a1 () {
console.log('a1 start')
await a2()
console.log('a1 end')
}
async function a2 () {
console.log('a2')
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout')
}, 0)
Promise.resolve().then(() => {
console.log('promise1')
})
a1()
let promise2 = new Promise((resolve) => {
resolve('promise2.then')
console.log('promise2')
})
promise2.then((res) => {
console.log(res)
Promise.resolve().then(() => {
console.log('promise3')
})
})
console.log('script end')
//-------
script start
a1 start
a2
promise2
script end
promise1
a1 end
promise2.then
promise3
setTimeout