Timeout limitations when using process.nextTick(), promises, and queueMicrotask()
例如,以下代码由 vm.runInNewContext()
执行,超时时间为 5 毫秒,它安排了一个无限循环在 promise 解决后运行。
计划的循环永远不会被超时中断:
const vm = require('vm');
function loop() {
while (1) console.log(Date.now());
}
vm.runInNewContext(
'Promise.resolve().then(loop);',
{ loop, console },
{ timeout: 5 }
);
Because of the internal mechanics of how the process.nextTick()
queue and
the microtask queue that underlies Promises are implemented within V8 and
Node.js, it is possible for code running within a context to "escape" the
timeout
set using vm.runInContext()
, vm.runInNewContext()
, and
vm.runInThisContext()
.
For example, the following code executed by vm.runInNewContext()
with a
timeout of 5 milliseconds schedules an infinite loop to run after a promise
resolves. The scheduled loop is never interrupted by the timeout:
const vm = require('vm');
function loop() {
while (1) console.log(Date.now());
}
vm.runInNewContext(
'Promise.resolve().then(loop);',
{ loop, console },
{ timeout: 5 }
);
This issue also occurs when the loop()
call is scheduled using
the process.nextTick()
and queueMicrotask()
functions.
This issue occurs because all contexts share the same microtask and nextTick queues.