js如何执行
- 从前到后,一行一行执行
- 如果某一行执行报错,则停止下面代码的执行
- 先把同步代码执行完,再执行异步
// 事例
console.log("Hi");
setTimeout(function cb1() {
console.log("cb1");
})
console.log("Bye")
// 执行结果 Hi Bye cb1
复制代码
js的异步任务在任务队列中排队,同步任务执行完毕,由于事件循环的作用把其推入到函数调用栈中执行
事件循环和任务队列
事件循环过程
- 如Call Stack为空(即同步代码执行完)Event Loop开始工作
- 轮询查找Callback Queue ,如有则移动到Call Stack 执行
- 然后继续轮询查找(永动机一样)
宏任务和微任务
- 宏任务: setTimeout , setInterval , Ajax ,DOM事件
- 微任务:Promise , async/await
- 微任务执行时机比宏任务要早
event Loop 和 DOM 渲染
宏任务和微任务以及dom渲染事如何运作的
- 每次Call Stack清空(即每次轮询结束),即同步任务执行完
- 每次执行完所有的同步任务后,会在任务队列中取出异步任务,先将所有微任务执行完成后
- 所有微任务执行完成,是DOM重新渲染的机会,DOM结构如有改变则重新渲染
- 最后才会去执行宏任务
从event loop解释,为何微任务执行更早
- 微任务是ES6语法规定的
- 宏任务是由浏览器规定的
promise then 的回调函数是在什么时候进入微任务队列的
- 关键在于,then 是在 resolve 之前被调用的,还是 resolve 之后呢
- then 在 resolve 之前,then 不会加微任务,而是缓存起来,resolve 看到缓存里又 then 的回调,于是加微任务
- resolve 在 then 之前,resolve 的时候还没有任何回调要执行,自然不会加微任务。then 的时候发现已经 fullfilled ,于是直接加微任务
- 也就是说,他们都有可能加,也都有可能不加,就看调用时的 promise 的状态了
- 在我的理解里,Promise 的实现中,then只会把回调放到一个数组里保存,所以我认为,reslove 后,才会进入微任务队列,存放callback 只是一个存放的操作
参考习题
第一题
async function fn() {
return 100
}
(async function() {
const a = fn();
const b = await fn();
console.log(a, b)
})();
(async function() {
console.log('hehe')
})()
// hehe Promise { 100 } 100
// #######################################################
第二题
console.log('1');
async function async1() {
console.log('2');
await async2();
console.log('3');
}
async function async2() {
console.log('4');
}
process.nextTick(function() {
console.log('5');
})
setTimeout(function() {
console.log('6');
process.nextTick(function() {
console.log('7');
})
new Promise(function(resolve) {
console.log('8');
resolve();
}).then(function() {
console.log('9')
})
})
async1();
new Promise(function(resolve) {
console.log('10');
resolve();
}).then(function() {
console.log('11');
});
console.log('12');
// 1
// 2
// 4
// 10
// 12
// 5
// 3
// 11
// 6
// 8
// 7
// 9
// #######################################################
第三题
new Promise(resolve => {
resolve();
}).then(() => {
console.log('then1');
console.log('推1-1入队');
new Promise(resolve => {
resolve();
}).then(() => {
console.log('then1-1');
console.log('推1-2入队');
}).then(() => {
console.log('then1-2')
});
console.log('推2入队');
}).then(() => {
console.log('then2');
console.log('推2-1入队');
new Promise(resolve => {
resolve();
}).then(() => {
console.log('then2-1');
console.log('推2-1-1入队');
new Promise((resolve) => {
resolve();
}).then(() => {
console.log('then2-1-1');
console.log('推2-1-2入队');
}).then(() => {
console.log('then2-1-2')
});
console.log('推2-2入队');
}).then(() => {
console.log('then2-2');
console.log('推2-3入队');
}).then(() => {
console.log('then2-3');
});
console.log('推3入队');
}).then(() => {
console.log('then3');
console.log('推3-1入队');
new Promise(res => {
res();
}).then(() => {
console.log('then3-1');
console.log('推3-2入队');
}).then(() => {
console.log('then3-2');
});
});
// then1
// 推1-1入队
// 推2入队
// then1-1
// 推1-2入队
// then2
// 推2-1入队
// 推3入队
// then1-2
// then2-1
// 推2-1-1入队
// 推2-2入队
// then3
// 推3-1入队
// then2-1-1
// 推2-1-2入队
// then2-2
// 推2-3入队
// then3-1
// 推3-2入队
// then2-1-2
// then2-3
// then3-2
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END