一、关于Javascript
javascript是一门单线程语言
二、Javascript事件循环
同步任务、异步任务
1.同步和异步任务分别进入不同的执行“场所”,同步任务进入主线程,异步任务进入Event Table并注册函数。
2.注册回调函数,Event Table将会把这个函数移入Event Queue.
3.主线程内的任务执行完毕,会从Event Queue读取对应的函数,进入主线程执行。
4.上述过程不断重复,就是常说的Event Loop(事件循环)
【注】判断主线程执行栈是否为空的方法:JS引擎中存在monitoring process进程,它会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数。
三、setTimeout
setTimeout这个函数,是经过指定时间后,把要执行的任务加入到Event Queue中,又因为是单线程任务要一个一个执行,如果前面的任务需要的时间太久,那么只能等着,导致真正的延迟时间远远大于设置的延时时间。
setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,意思就是不用再等多少秒了,只要主线程执行栈内的同步任务全部执行完成,栈为空就马上执行。
【补充】:关于setTimeout,即便主线程为空,0毫秒实际上也是达不到的。根据HTML的标准,最低是4毫秒。
【延伸】:setTimeout有最小时间间隔限制,HTML5标准为4ms,小于4ms按照4ms处理,但是每个浏览器实现的最小间隔都不同。
setInterval的最短间隔时间是10毫秒,也就是说,小于10毫秒的时间间隔会被调整到10毫秒。
四、setInterval
对于setInterval(fn,ms)来说,我们已经知道不是每过ms秒会执行一次fn,而是每过ms秒,会有fn进入Event Queue。一旦setInterval的回调函数fn执行时间超过了延迟时间ms,那么就完全看不出来有时间间隔了。(即如果setInterval的回调执行时间长于指定的延迟,setInterval将无间隔的一个接一个执行)
五、Promise与process.nextTick(callback)
- macro-task(宏任务):包括整体代码script,setTimeout,setInterval
当我们在执行setTimeout任务中遇到setTimeout时,它仍然会将对应的任务分发到setTimeout队列中去,但是该任务就得等到下一轮事件循环执行了。
【注】:macro-task 中setTimeout的优先级高于setIImmediate
- micro-task(微任务):Promise,process.nextTick
【注】:micro-task 中process.nextTick的优先级高于Promise
//1,6,7,8,2,3,4,5