标签:div 类型 loop queue proc 同步 遇到 结束 settime
首先,在说这个之前,我们先把event loop再复习一遍:
JS主线程不断的循环往复的从任务队列中读取任务,执行任务,其中运行机制称为事件循环(event loop).那么提到这里,在高层次上,JavaScript中有microtasks和macrotasks,它们是异步任务的一种类型.Microtasks的优先级要高于macrotasks,macrotasks用于处理I/O和计时器等事件.每次执行一个,microtask为async/await和Promise实现延迟执行,宁在每个task结束时执行.在每一个事件循环之前,microtask队列总是被执行完毕.
我们在看看经常见到的一些微任务与宏任务的区别:
1.微任务:process.nextTick,promise,MutationObserver
2.宏任务:setTImeout,setTimeInterval,setImmediate,I/O,UI渲染
注意哈:每个event loop都会有一个microtask queue,也会有一个或多个macrotask queue,一次任务可以放入macrotask queue,也可以放入microtask queue中.每一次event loop,会首先执行microtask queue,执行完成后,会提取macotask queue的一个任务加入macrotask queue,接着执行microtask queue,依次执行下去直至所有任务执行结束.
我们再来看下异步执行机制吧.JS主线程拥有一个执行栈(同步任务)与一个任务队列,主线程回依次执行代码.当遇到同步任务时,会先将函数入栈,函数运行后再将该函数出栈;当遇到异步任务时,这些任务会返回一个值,让主线程不在此阻塞,使得主线程继续执行下去,而真正的任务交给了浏览器内核来执行,浏览器内核执行结束后,会将该任务事先定义好的回调函数加入相应的任务队列中.当JS主线程前空了执行栈后,会按先入先出的顺序读取microtasks queue的回调函数,并该函数入栈,继续运行执行栈,直到情况执行栈,再去读取任务队列.当微任务队列的任务执行完成后,会提取宏任务队列的一个任务加入微任务队列,接着继续执行微任务队列,依次执行下去直到所有任务全部执行结束.
接下来,我们来依次看看几个比较常用的异步:
1.setTimeout
console.log(‘start1‘); setTimeout(function(){ console.log(‘macro‘); },0) console.log(‘22‘) //输出顺序为:start1->22->macro
2.Promise
Promise本身是同步的立即执行函数,当在excutor中执行resolve或者reject的时候,此时是异步操作,会先执行then/catch等,当主栈完成后,才会去调用resolve/reject中存放的方法执行
console.log(‘start‘) let promise1=new Promise(function(resolve){ console.log(‘promise1‘) resolve() console.log(‘1end‘) }).then(function(){ console.log(‘promise2‘) }) setTimeout(function(){ console.log(‘setTimeout‘) }) console.log(‘send‘) //start->promise1->1end->send->promise2->setTimeout
当JS主线程执行到Promise对象时,promise1.then()的回调就是一个task,promise1是resolved或rejected,那这个task就会放入当前事件循环回合的microtask queue中.如果是pending,这个task就会放入事件循环的某个回合的microtask queue中,我们再来看些例子吧:
const p=Promise.resolve();//1.p的状态为resolve (async ()=>{ await p;//2.返回,并将函数体后面的console放入下一个事件循环的microtask queue中 console.log(‘await end‘);//5.执行,打印 })(); p.then(()=>{ console.log(‘then 1‘);//3.p的状态变为resolve,会把p.then()放入当前事件循环的microtask queue中,因此打印then 1 }.then(()=>{ console.log("then 2");//4.打印then2 }) //输出:then 1->then 2->await end
console.log(‘start‘); setTimeout(function(){ console.log(‘setTimeout‘) },0) Promise.resolve().then( function(){ console.log(‘promise1‘) }).then(function(){ console.log(‘promise2‘) }); console.log(‘end‘); //输出结果:start->end->promise1->promise2->setTimeout
3.async await
async function async1(){ console.log(‘async1 start‘); await async2(); console.log(‘async2 end‘) } async function async2(){ console.log(‘async2‘) } console.log(‘script start‘) async1(); console.log(‘script end‘) //script start->async1 start->async2->scirpt end ->async2 end
async函数返回一个Promise对象,当函数执行的时候,一旦遇到await就会先返回,等到出发的异步操作完成,再执行函数体被那个后面的语句,可以理解为是让出了线程,跳出了async函数体.
标签:div 类型 loop queue proc 同步 遇到 结束 settime
原文地址:https://www.cnblogs.com/ljylearnsmore/p/14537145.html