Fix process.nextTick so thrown errors don't confuse it.
If the function for a process.nextTick throws an error, then the splice() never removes that function from the nextTickQueue array. This makes sure the functions that have been run in _tickCallback get removed regardless of errors. Also add a test for this.
This commit is contained in:
Родитель
4fdebab005
Коммит
57642e2349
12
src/node.js
12
src/node.js
|
@ -49,9 +49,17 @@ var nextTickQueue = [];
|
|||
process._tickCallback = function () {
|
||||
var l = nextTickQueue.length;
|
||||
if (l === 0) return;
|
||||
for (var i = 0; i < l; i++) {
|
||||
nextTickQueue[i]();
|
||||
|
||||
try {
|
||||
for (var i = 0; i < l; i++) {
|
||||
nextTickQueue[i]();
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
nextTickQueue.splice(0, i+1);
|
||||
throw e;
|
||||
}
|
||||
|
||||
nextTickQueue.splice(0, l);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
common = require("../common");
|
||||
assert = common.assert
|
||||
|
||||
var order = [],
|
||||
exceptionHandled = false;
|
||||
|
||||
// This nextTick function will throw an error. It should only be called once.
|
||||
// When it throws an error, it should still get removed from the queue.
|
||||
process.nextTick(function() {
|
||||
order.push('A');
|
||||
// cause an error
|
||||
what();
|
||||
});
|
||||
|
||||
// This nextTick function should remain in the queue when the first one
|
||||
// is removed.
|
||||
process.nextTick(function() {
|
||||
order.push('C');
|
||||
});
|
||||
|
||||
process.addListener('uncaughtException', function() {
|
||||
if (!exceptionHandled) {
|
||||
exceptionHandled = true;
|
||||
order.push('B');
|
||||
// We call process.nextTick here to make sure the nextTick queue is
|
||||
// processed again. If everything goes according to plan then when the queue
|
||||
// gets ran there will be two functions with this being the second.
|
||||
process.nextTick(function() {
|
||||
order.push('D');
|
||||
});
|
||||
}
|
||||
else {
|
||||
// If we get here then the first process.nextTick got called twice
|
||||
order.push('OOPS!');
|
||||
}
|
||||
});
|
||||
|
||||
process.addListener('exit', function() {
|
||||
assert.deepEqual(['A','B','C','D'], order);
|
||||
});
|
||||
|
Загрузка…
Ссылка в новой задаче