javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变。所以一切javascript版的"多线程"都是用单线程模拟出来的,一切javascript多线程都是纸老虎!
javascript事件循环
1.当执行JS代码时,生成执行栈,同步和异步任务分别进入不同的执行"场所",同步的进入主线程执行栈,异步的进入Event Table并注册函数。
2.当异步任务完成时,结果会以callback形式通知主进程,如果主进程忙碌,Event Table会将这个结果移入Event Queue。
3.主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,生成执行栈进行运行。
上述过程会不断重复,也就是常说的Event Loop(事件循环)。
setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行。
macro-task(宏任务):包括整体代码script,setTimeout,setInterval,setImmediate
micro-task(微任务):Promise.then,process.nextTick,MutationObserver
宏任务产生微任务
JS异步有一个机制,遇到宏任务和微任务,先把宏任务放到任务队列,再把微任务放入任务队列,两个队列不是同一个队列,但是往外拿的时候,先处理微任务的回调函数,再处理宏任务的回调函数
node环境下异步执行顺序不一样,node在处理一个任务队列的时候,不管怎么,都会先处理完这个任务队列,再清空微任务队列
举例:
处理完同步任务之后,宏任务队列中有两个宏任务,主程序会先清空微任务队列,再处理宏任务,而如果处理第一个宏任务的时候,会产生两个微任务,浏览器会在处理完第一个宏任务之后清空微任务队列再执行下一个宏任务,而node则会把这两个宏任务做完之后一起清空微任务队列
process.nextTick比promise.then快