Open shhider opened 5 years ago
迁移过来,16 年 12 月写的。 因为这两天要做一些regularjs相关的一些工作,所以终于开始有目标性地看一看regular的代码了。那从regular的代码里,能够发散出一些知识点,就打算记录在这个系列里,希望能够坚持记录下去。
迁移过来,16 年 12 月写的。
因为这两天要做一些regularjs相关的一些工作,所以终于开始有目标性地看一看regular的代码了。那从regular的代码里,能够发散出一些知识点,就打算记录在这个系列里,希望能够坚持记录下去。
// src/util.js _.nextTick = typeof setImmediate === 'function'? setImmediate.bind(win) : function(callback) { setTimeout(callback, 0) }
setImmediate其实是一个新的定时器方法,(截至本文)只有在IE11/Edge与Nodejs中支持该方法。从regular的代码里可以得知,其实它的行为,和setTimeout(0)是一样的,都是将某任务立即添加到任务队列中——稍后执行。
setTimeout(0)
两者之间实际上是有微小的差异的。HTML5规范中规定,setTimeout方法的timeout最小值是4ms,若小于4,则会自动增加为4ms;而setImmediate是没有类似的限制的。因此,setImmediate指定的回调通常比setTimeout早一些执行(具体在各环境的执行顺序未试验)。
If the currently running task is a task that was created by the setTimeout() method, and timeout is less than 4, then increase timeout to 4.
在Nodejs中,nextTick其实是一个已有的方法,属于process的一个方法,同样是为了实现稍后执行的效果,但执行时机不一样,相对其他定时器方法要更早执行。
On the next loop around the event loop call this callback. This is not a simple alias to setTimeout(fn, 0), it's much more efficient.
没有试验过,避免误人子弟,其他细节等我了解后再写。
那前面的内容,都涉及到一个很重要的概念——事件循环(Event Loop)。先上图(图片来源:Philip Roberts: Help, I’m stuck in an event-loop. on Vimeo):
(浏览器环境中)JavaScript的运行环境包含一个执行栈(Stack),当前任务中的函数将在栈内一步步地执行。执行过程中,除了ECMAScript各内置方法外,还会调用Web API,进行DOM、BOM等操作,这其中就会涉及到异步事件和定时任务。当异步事件或定时任务被触发,指定的回调函数执行任务就会被加入到任务队列(Callback Queue)中,等待执行。
当一个任务执行结束,任务栈为空时,JS引擎就会查询任务队列,若队列中有待执行的任务,就读取并放入执行栈开始执行;若为空,则继续查询,直到队列中出现新的任务。「事件循环」就是指JS引擎重复从任务队列中取任务、执行任务的过程。
基于这样的「事件循环」机制,JavaScript可以在单线程中实现「绝不阻塞」的并发执行。
(其实这里的「单线程」是指负责解释和执行JavaScript代码的主线程,其它像定时器、文件读写等也都会有各自单独的线程。)
了解了事件循环之后,setTimeout等定时任务的时间「误差」也就可以理解了,因为加入任务队列时,前面还有好多任务排着队呢。同时,process.nextTick的「强制性」,就是因为它相当于把任务「插队」到了任务队列的队首。
process.nextTick
!!TODO!!
setImmediate 与 setTimeout
setImmediate其实是一个新的定时器方法,(截至本文)只有在IE11/Edge与Nodejs中支持该方法。从regular的代码里可以得知,其实它的行为,和
setTimeout(0)
是一样的,都是将某任务立即添加到任务队列中——稍后执行。两者之间实际上是有微小的差异的。HTML5规范中规定,setTimeout方法的timeout最小值是4ms,若小于4,则会自动增加为4ms;而setImmediate是没有类似的限制的。因此,setImmediate指定的回调通常比setTimeout早一些执行(具体在各环境的执行顺序未试验)。
process.nextTick
在Nodejs中,nextTick其实是一个已有的方法,属于process的一个方法,同样是为了实现稍后执行的效果,但执行时机不一样,相对其他定时器方法要更早执行。
没有试验过,避免误人子弟,其他细节等我了解后再写。
Event Loop
那前面的内容,都涉及到一个很重要的概念——事件循环(Event Loop)。先上图(图片来源:Philip Roberts: Help, I’m stuck in an event-loop. on Vimeo):
(浏览器环境中)JavaScript的运行环境包含一个执行栈(Stack),当前任务中的函数将在栈内一步步地执行。执行过程中,除了ECMAScript各内置方法外,还会调用Web API,进行DOM、BOM等操作,这其中就会涉及到异步事件和定时任务。当异步事件或定时任务被触发,指定的回调函数执行任务就会被加入到任务队列(Callback Queue)中,等待执行。
当一个任务执行结束,任务栈为空时,JS引擎就会查询任务队列,若队列中有待执行的任务,就读取并放入执行栈开始执行;若为空,则继续查询,直到队列中出现新的任务。「事件循环」就是指JS引擎重复从任务队列中取任务、执行任务的过程。
基于这样的「事件循环」机制,JavaScript可以在单线程中实现「绝不阻塞」的并发执行。
(其实这里的「单线程」是指负责解释和执行JavaScript代码的主线程,其它像定时器、文件读写等也都会有各自单独的线程。)
了解了事件循环之后,setTimeout等定时任务的时间「误差」也就可以理解了,因为加入任务队列时,前面还有好多任务排着队呢。同时,
process.nextTick
的「强制性」,就是因为它相当于把任务「插队」到了任务队列的队首。Web Worker
!!TODO!!
Reference