setImmediate函数的代码在lib/timer.js。...function setImmediate(callback, arg1, arg2, arg3) { if (typeof callback !...var immediate = queue.head; const tail = queue.tail; // Clear the linked list early in case new `setImmediate...所以setImmediate的执行时机是在uv__run_check这个阶段。另外提一下的就是setImmediate和setTimeout谁先谁后的问题。这个其实是不一定的。...从uv_run中我们看到执行定时器的代码比是比uv__run_check先的,但是如果我们在执行完定时器之后,uv__run_check之前,又新增了一个定时器和执行了setImmediate,那么setImmediate
我们从setImmediate开始分析, function setImmediate(callback, arg1, arg2, arg3) { if (typeof callback !...args[i - 1] = arguments[i]; } break; } return new Immediate(callback, args); } setImmediate...immediate_idle_handle(), [](uv_idle_t*){ }); } else { uv_idle_stop(immediate_idle_handle()); } } 这是setImmediate...outstandingQueue.head = null; // 全部节点执行完 immediateInfo[kHasOutstanding] = 0; } 这就是setImmediate
setImmediate() vs setTimeout() 在 JavaScript 中的区别 在 JavaScript 中,setImmediate() 和 setTimeout() 都用于调度任务...("setImmediate 2"); }); 当你运行这段代码时,你可能期望 setTimeout 回调按定义的顺序执行,然后是 setImmediate 回调。...但你在控制台中看到的是: setTimeout 1 setImmediate 1 setImmediate 2 setTimeout 2 如果这让你感到困惑,不要担心。让我们解开其中的原因。...setImmediate() 另一方面,setImmediate() 设计用于在 I/O 事件完成后执行回调,在同一事件循环迭代中。...为什么 setImmediate 回调会一起运行? 相同的事件循环周期:两个 setImmediate 调用在事件循环的同一个周期(或循环)中被放置到宏任务队列中。
而setImmediate接口则是为此而生的。...理论上通过setImmediate执行异步调用的延时一定比通过setTimeout的短,但事实又是如何呢? ...通过setImmediate的异步调用的延时不是0ms哦! 2. 而且有时候setImmediate的延时比setTimeout的多1~2ms哦! 3....而且setImmediate和setTimeout的延时均比img元素onerror事件的延时长哦! 推测: 1....对于setImmediate的延时有时比setTimeout的要长,由于setImmediate要先监控调用栈,若调用栈为空才压栈,那么在压栈之前event loop已经将setTimeout事件的回调函数压栈了
我们首先看一下下面这段代码 setTimeout(()=>{ console.log('setTimeout'); },0) setImmediate(()=>{ console.log('setImmedate...setTimeout是属于定时器阶段,setImmediate是属于check阶段。顺序上定时器阶段是比check更早被执行的。...在分析nodejs的setImmediate和setTimeout的文章中已经介绍过这两个函数对应的实现原理。这里就不细说了。其中setTimeout的实现代码里有一个很重要的细节。...nodejs启动的时候,会编译执行上面的代码,开始一个定时器,挂载一个setImmediate节点在队列。...这时候就会执行setImmediate的回调。所以,一开始的那段代码的输出结果是取决于启动定时器的时间到libuv执行定时器阶段是否过去了1毫秒。
笼统的知道setImmediate比setTimeout(fn, 0)先执行是不够的,因为有些情况下setTimeout(fn, 0)是会比setImmediate先执行的。...setImmediate和setTimeout 上面的这个流程说简单点就是在一个异步流程里,setImmediate会比定时器先执行,我们写点代码来试试: console.log('outer');...和我们前面讲的一样,setImmediate先执行了。...(() => { console.log('setImmediate'); }); }); 复制代码 这里setTimeout和setImmediate在readFile的回调里面...,由于readFile回调是I/O操作,他本身就在poll阶段,所以他里面的定时器只能进入下个timers阶段,但是setImmediate却可以在接下来的check阶段运行,所以setImmediate
注意:如果进行到了poll阶段,setImmediate()具有最高优先级,只要poll队列为空且注册了setImmediate(),无论是否有timers达到下限时间,setImmediate()的代码都先执行...2.2 setImmediate() setImmediate()是放在check阶段执行的,实际上是一个特殊的timer,跑在event loop中一个独立的阶段。...('setImmediate') }) // 输出不稳定 setTimeout与setImmediate先后入队之后,首先进入的是timers...// 输出 开始了 setImmediate setTimeout 这里我们就会发现,setImmediate永远先于setTimeout执行。...再来个栗子: 同样的,这段代码也是一样的道理: setTimeout(() => { setImmediate(() => console.log('setImmediate') );
如果poll queue空了,如果代码中调用了setImmediate,那么将会立马跳到下一个check phase,然后执行setImmediate中的callback。...如果没有调用setImmediate,那么会继续等待新来的callback被加入到queue中,并执行。 check 主要来执行setImmediate的callback。...setTimeout 和 setImmediate的区别 setTimeout和setImmediate有什么不同呢?...process.nextTick 和 setImmediate 的区别 process.nextTick 是立马在当前phase执行callback,而setImmediate是在check阶段执行callback...所以process.nextTick要比setImmediate的执行顺序优先。 实际上,process.nextTick和setImmediate的语义应该进行互换。
setImmediate() 与 setTimeout(0) 的对比 setImmediate的回调是异步的,和setTimeout回调性质一致。...eventloop再向下到达check队列执行setImmediate的回调。最终顺序就是「setTimeout -> setImmediate」了。...与setImmediate时间差距 可见setTimeout远比setImmediate耗时多得多 这是因为setTimeout不仅有主代码执行的时间消耗。...'setImmediate')) }) 上边这种代码逻辑,不管执行多少次,肯定都是先执行setImmediate。...扩展:为什么有了setImmediate还要有nextTick和Promise? 一开始设计的时候,setImmediate充当了微队列的作用(虽然他不是)。
node 中还存在一些与 I/O 无关的异步 API,setTimeout()、setInteval()、setImmediate()、process.nextTick() process.nextTick...()=> idle 观察者 setImmediate() => check 观察者 事件循环对观察者的检查有先后顺序,idle观察者先于 I/O 观察者,I/O 观察者先于 check 观察者。...(() => { console.log("setImmediate-1"); process.nextTick(function () { console.log("setImmediate...-1-process.nextTick-1"); }); }); setImmediate(() => { console.log("setImmediate-2"); }); process.nextTick...// setImmediate-1 // setImmediate-1-process.nextTick-1 // setImmediate-2 // 读取的文件内容1 // 读取的文件内容2 //
(setTimeout,setInterval)回调队列 idle 观察者中存放 process.nextTick() 回调队列 poll 观察者中存放了读取文件的回调队列 check 观察者中存放 setImmediate...()的回调函数 setImmediate(function () { console.log('setImmediate延迟执行1'); // 进入下次循环 process.nextTick...(function () { console.log('最后执行'); }); }); setImmediate(function () { console.log('setImmediate...延迟执行2'); }); console.log('正常执行'); 输出结果 正常执行 nextTick延迟执行1 nextTick延迟执行2 setImmediate延迟执行1 setImmediate...代码中idle观察者中有两个process.nextTick的回调,check观察者中有两个setImmediate的回调。
(vue2.0已经废弃使用此API) setImmediate/setTimeout setImmediate为IE特有的,我们可以在IE浏览器环境下做测试 setImmediate(() => {...阶段 此阶段专门执行setImmediate的回调,当poll阶段进入空闲状态,并且setImmediate队列中有callback时,事件循环进入这个阶段 close阶段 当一个socket连接或者一个...') }) // => setImmediate -> timeout // or timeout -> setImmediate 例子代码地址 多运行几次,运行结果是不一定的,这取决于运行代码的环境。...console.log('timeout') }, 0) setImmediate(() => { console.log('setImmediate') }) }) //...=> setImmediate -> timeout 例子代码地址 回顾上面提到的阶段,在I/O事件的回调中,setImmediate的回调永远优先于setTimeout的回调执行。
(),分两种情况: 若有预设的setImmediate(), event loop将结束poll阶段进入check阶段,并执行check阶段的任务队列 若没有预设的setImmediate(),event...check 阶段 setImmediate是一个特殊的定时器方法,它占据了事件循环的一个阶段,整个「check 阶段」就是为setImmediate方法而设置的。...setImmediate 对比 setTimeout setImmediate() 和 setTimeout() 很类似,但是基于被调用的时机,他们也有不同表现。...setImmediate方法和process.nextTick方法很相似,二者经常被拿来放在一起比较,从语义角度看,setImmediate() 应该比 process.nextTick() 先执行才对...这是因为setImmediate不会生成call stack。
}); setImmediate(() => { console.log('#2'); }); setImmediate(() => { console.log('#3'); setImmediate...setImmediate() fires on the following iteration or ‘tick’ of the event loop P.S.setImmediate描述不是十分严谨...,这里不展开 setTimeout与setImmediate setTimeout(function() { console.log('setTimeout') }, 0); setImmediate...setTimeout setImmediate 但实际情况是: // 1st setImmediate setTimeout // 2nd setImmediate setTimeout // 3rd...setImmediate setTimeout // 4th setTimeout setImmediate // 5th setImmediate setTimeout // 6th setTimeout
macro-task 大概包括: setTimeout setInterval setImmediate script(整体代码) I/O 操作等。...检查阶段(check):setImmediate() 回调函数在这里执行 关闭事件回调阶段(close callback):一些关闭的回调函数,如:socket.on('close', ...)。...check 阶段执行回调 如果没有 setImmediate 回调需要执行,会等待回调被加入到队列中并立即执行回调,这里同样会有个超时时间设置防止一直等待下去,一段时间后自动进入 check 阶段。...().then(() => console.log('promise resolve')) }); setImmediate(() => console.log('immediate3')); setImmediate...(() => console.log('next tick')) }); setImmediate(() => console.log('timeout3')); setImmediate(() =>
微任务 Promise 、process.nextTick 可以看到,在Node.js对比浏览器多了两个任务,分别是宏任务 setImmediate 和 微任务 process.nextTick setImmediate...就一定比 setImmediate 先执行呢?...我们来看个例子 setTimeout(() => { console.log('setTimeout'); }, 0) setImmediate(() => { console.log...('setImmediate'); }) 我们用node运行该段代码多次,发现得到了如下两种结果: // 第一种结果 setTimeout setImmediate // 第二种结果 setImmediate...{ console.log('setImmediate'); }); }); 多次运行代码发现,每次都是先打印了 setImmediate,然后才打印的 setTimeout 四、结束语 一篇完整的
当然,下面的小案例同理:setTimeout(() => { setImmediate(() => { console.log('setImmediate'); });...最后案例代码片段1:setImmediate(function(){ console.log("setImmediate"); setImmediate(function(){ console.log...\92809\Desktop\node_test>node test.js setImmediate nextTick 嵌套setImmediate*/解析:事件循环check阶段执行回调函数输出...setImmediate,之后输出nextTick。...嵌套的setImmediate在下一个事件循环的check阶段执行回调输出嵌套的setImmediate。
在IE11/Edge中,setImmediate延迟可以在1ms以内,而setTimeout有最低4ms的延迟,所以setImmediate比setTimeout(0)更早执行回调函数。...(function testSetImmediate() { const label = 'setImmediate'; console.time(label); setImmediate...(() => { console.timeEnd(label); }); })(); Edge输出:setImmediate: 0.555 毫秒 很明显,setImmediate...而且Promise的延迟比setImmediate更低,意味着Promise比setImmediate先执行。...function testSetImmediate() { const label = 'setImmediate'; console.time(label); setImmediate
领取专属 10元无门槛券
手把手带您无忧上云