所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
运行机制:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
这种运行机制又称为Event Loop(事件循环)。
宏任务和微任务都是异步任务,主要区别在于他们的执行顺序。
宏任务:
包括整体代码script,setTimeout,setInterval、setImmediate。
微任务:
原生Promise(有些实现的promise将then方法放到了宏任务中)、process.nextTick、 MutationObserver
js异步有一个机制,就是遇到宏任务,先执行宏任务,将宏任务放入event queue,然后再执行微任务,将微任务放入event queue最骚的是,这两个queue不是一个queue。当你往外拿的时候先从微任务里拿这个回调函数,然后再从宏任务的queue上拿宏任务的回掉函数。
例子1:
setTimeout(()=>{ console.log('setTimeout1') },0) let p = new Promise((resolve,reject)=>{ console.log('Promise1') resolve() }) p.then(()=>{ console.log('Promise2') })
例子2:
Promise.resolve().then(()=>{ console.log('Promise1') setTimeout(()=>{ console.log('setTimeout2') },0) }) setTimeout(()=>{ console.log('setTimeout1') Promise.resolve().then(()=>{ console.log('Promise2') }) },0)
输出结果是Promise1,setTimeout1,Promise2,setTimeout2
1. 查看微任务队列,取出微任务队列中的值,输出 Promise 1。
2. 生成一个异步任务宏任务setTimeout2。
3. 微任务队列清空,查看宏任务队列,setTimeout1在setTimeout2之前,取出setTimeout1
生成一个promise2的微任务。
清空微任务队列中的值,输出 Promise2。
4. 查看宏任务队列,输出setttimeout2。
网友回答文明上网理性发言 已有0人参与
发表评论: