js同步异步
同步任务:指的是在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务
异步任务: 指的是不进入主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
js异步运行机制
异步执行的运行机制如下(同步任务也如此,因为它可以被视为没有异步任务的异步执行):
所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)
主线程之外,还存在一个“任务队列”,只要异步任务有了运行结果,就在“任务队列”之中放置一个事件
3.一旦“执行栈”中的所有同步任务执行完毕,系统就会读取“任务队列”,看看里面有哪些事件。那些对应的异步任务,于是结束等待,进入执行栈,开始执行
主线程不断重复第3步
[图片上传失败...(image-77d9ff-1551700016485)]
微任务和宏任务
macro-task(宏任务):包括整体代码script,setTimeout,setInterval
micro-task(微任务):Promise,process.nextTick
不同类型的任务会进入不同的Event Queue,有宏任务的队列和微任务的队列。
事件循环的顺序,决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。
整段代码作为宏任务进入主线程
遇到settimeout,将其回调函数注册后分发到宏任务Event Queue。
遇到了Promise,new Promise立即执行,then函数分发到微任务Event Queue
遇到console.log(),立即执行
第一个宏任务执行结束,看看有什么微任务,发现有then,执行
第二轮循环,发现宏任务settimeout的回调函数,执行。
结束。
分析代码
console.log('1');setTimeout(function(){console.log('2'); process.nextTick(function(){console.log('3'); })newPromise(function(resolve){console.log('4'); resolve(); }).then(function(){console.log('5') })})process.nextTick(function(){console.log('6');})newPromise(function(resolve){console.log('7'); resolve();}).then(function(){console.log('8')})setTimeout(function(){console.log('9'); process.nextTick(function(){console.log('10'); })newPromise(function(resolve){console.log('11'); resolve(); }).then(function(){console.log('12') })})
答案
1 7 6 8 、2 4 3 5、 9 11 10 12
链接://www.greatytc.com/p/5af66e109eca