Chapter 1:Node.js环境下的异步函数
Timer
Node对两个Timer的超时时间做了个小trick, 任何大于TIMEOUT_MAX
小于1ms的超时都被视为1ms.
setTimeout 和 setInterval 在Node下的封装基本上一样, 这里单拿前者举例.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
exports.setTimeout = function(callback, after) { after *= 1; // coalesce to number or NaN // 保证setTimeout永远会延时执行 if (!(after >= 1 && after <= TIMEOUT_MAX)) { after = 1; // schedule on next tick, follows browser behaviour } // ... var ontimeout = callback; timer._onTimeout = ontimeout; // ... exports.active(timer); return timer; }; |
setImmediate
官方文档对 setImmediate 并不准确, 基本上让所有没读过源码(包括读得不仔细)的人对其产生极大误解.
主要来自 setImmediate 和 setTimeout(0) 谁先谁后的问题,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
exports.setImmediate = function(callback, arg1, arg2, arg3) { var i, args; var len = arguments.length; var immediate = new Immediate(); L.init(immediate); // ... // 这里是setImmediate能执行的关键, c++作用域里会检查`_needImmediateCallback` // c++那部分代码太长我就不贴了, 全在src/node.cc里, 自己去看. if (!process._needImmediateCallback) { process._needImmediateCallback = true; process._immediateCallback = processImmediate; } // ... return immediate; }; |
process.nextTick
这个在异步函数里优先级最高大家都知道, 属于idle
观察者也清. 代码在
src/node.js 里实现.
代码很长, 不多说, 所有 process.nextTick 堆积的任务都会在事件循环的 next tick (后面讲)里一口气执行.
这里还有一个重点:
_tickCallback 函数是idle
观察者在
next tick 里的主回调函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
function _tickCallback() { var callback, args, tock; do { while (tickInfo[kIndex] < tickInfo[kLength]) { tock = nextTickQueue[tickInfo[kIndex]++]; callback = tock.callback; args = tock.args>callback; args = tock.argsine-height: 15px !important;font-size: 13px !important;">setTimeout 和
setInterval 在Node下的封装基本上一样, 这里单拿前者举例.
setImmediate官方文档对 setImmediate 并不准确, 基本上让所有没读过源码(包括读得不仔细)的人对其产生极大误解. 主要来自 setImmediate 和 setTimeout(0) 谁先谁后的问题,
process.nextTick这个在异步函数里优先级最高大家都知道, 属于 代码很长, 不多说, 所有 process.nextTick 堆积的任务都会在事件循环的 next tick (后面讲)里一口气执行. 这里还有一个重点:
_tickCallback 函数是
|