事件循环2(微任务 和宏任务)
JS是单线程,一次只能执行一个任务,当有一个耗时很长时,有一个在后面等待,会造成堵塞,异步的目的就是处理堵塞,提升性能。
一、promise对象
promise调用内部函数。
promise有三种对象:
1.pending:待定,未初始化
2.resolved:异步成功
3.rejected:异步操作失败
promise对象状态改变:
1.从pending到resolved
2.从pending到rejected
参数 resolve和reject无论哪个值被调用,状态都不可以撤销,被调用后,then方法返回这个被调用的值。
console.log("你好"); let a=new Promise(function(resolve, reject){ console.log("第一个对象"); setTimeout(function(){ resolve("aha!"); console.log("huhu"); },1000); }) setTimeout(()=>{ console.log("再见"); },0) console.log(45); //输出:你好 第一个对象 45 再见 aha!
二、宏任务和微任务
1.宏任务
可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。
(macro)task->渲染->(macro)task->... //完成第一个宏任务之后开始渲染,之后再执行下一个任务
宏任务包括:
script(整体代码) setTimeout setInterval I/O UI交互事件 postMessage MessageChannel setImmediate(Node.js 环境)
2.微任务
当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。
微任务包括:
Promise.then
Object.observe
MutaionObserver
process.nextTick(Node.js 环境)
过程:
- 执行一个宏任务(栈中没有就从事件队列中获取)
- 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
- 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
- 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
- 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
console.log("1"); new Promise(function(resolve,reject){ console.log(2); resolve(); }).then(function(){ console.log(3); }); setTimeout(function(){ console.log(4); }) console.log(5); //输出:1 2 5 3 4

浙公网安备 33010602011771号