Add process.nextTick()

This is a replacement for the common hack:

  setTimeout(cb, 0);

It's much more efficient.
This commit is contained in:
Ryan Dahl 2010-01-18 10:27:27 -08:00
parent aeb7d6d168
commit 8abeffa9ea
4 changed files with 61 additions and 6 deletions

View File

@ -123,6 +123,9 @@ Returns the memory usage of the Node process. It looks like this
+ +
+heapTotal+ and +heapUsed+ refer to V8's memory usage. +heapTotal+ and +heapUsed+ refer to V8's memory usage.
+process.nextTick(callback)+::
On the next loop around the event loop call this callback.
+process.exit(code=0)+:: +process.exit(code=0)+::
Ends the process with the specified code. By default it exits with the Ends the process with the specified code. By default it exits with the
success code 0. success code 0.

View File

@ -7,9 +7,9 @@ exports.parse = function(options) {
try { try {
var stream = new exports.Stream(options); var stream = new exports.Stream(options);
} catch (e) { } catch (e) {
setTimeout(function() { process.nextTick(function() {
promise.emitError(e); promise.emitError(e);
}, 0); });
return promise; return promise;
} }

View File

@ -377,6 +377,30 @@ var eventsModule = createInternalModule('events', function (exports) {
var events = eventsModule.exports; var events = eventsModule.exports;
// nextTick()
var nextTickQueue = [];
var nextTickWatcher = new process.IdleWatcher();
nextTickWatcher.setPriority(process.EVMAXPRI); // max priority
nextTickWatcher.callback = function () {
var l = nextTickQueue.length;
while (l--) {
var cb = nextTickQueue.shift();
cb();
}
if (nextTickQueue.length == 0) nextTickWatcher.stop();
};
process.nextTick = function (callback) {
nextTickQueue.push(callback);
nextTickWatcher.start();
};
// Signal Handlers // Signal Handlers
function isSignal (event) { function isSignal (event) {
@ -829,9 +853,9 @@ function loadModule (request, parent) {
debug("found " + JSON.stringify(id) + " in cache"); debug("found " + JSON.stringify(id) + " in cache");
// In cache // In cache
var module = moduleCache[id]; var module = moduleCache[id];
setTimeout(function () { process.nextTick(function () {
loadPromise.emitSuccess(module.exports); loadPromise.emitSuccess(module.exports);
}, 0); });
} else { } else {
debug("looking for " + JSON.stringify(id) + " in " + JSON.stringify(paths)); debug("looking for " + JSON.stringify(id) + " in " + JSON.stringify(paths));
// Not in cache // Not in cache
@ -868,11 +892,11 @@ Module.prototype.loadObject = function (filename, loadPromise) {
var self = this; var self = this;
// XXX Not yet supporting loading from HTTP. would need to download the // XXX Not yet supporting loading from HTTP. would need to download the
// file, store it to tmp then run dlopen on it. // file, store it to tmp then run dlopen on it.
setTimeout(function () { process.nextTick(function () {
self.loaded = true; self.loaded = true;
process.dlopen(filename, self.exports); // FIXME synchronus process.dlopen(filename, self.exports); // FIXME synchronus
loadPromise.emitSuccess(self.exports); loadPromise.emitSuccess(self.exports);
}, 0); });
}; };
function cat (id, loadPromise) { function cat (id, loadPromise) {

View File

@ -0,0 +1,28 @@
process.mixin(require("./common"));
var complete = 0;
process.nextTick(function () {
complete++;
process.nextTick(function () {
complete++;
process.nextTick(function () {
complete++;
});
});
});
setTimeout(function () {
process.nextTick(function () {
complete++;
});
}, 50);
process.nextTick(function () {
complete++;
});
process.addListener('exit', function () {
assert.equal(5, complete);
});