function-timeout 是一个可以使同步函数支持超时的 npm 库,实现原理是把函数放在 node:vm
中执行,因为 vm.Script()
返回的 script 对象就支持传入 timeout
选项。
vm 是 virtual machine 的缩写,意思是在 Node.js 中创建一个虚拟环境,用来执行不希望在主环境中执行的代码。
创建一个 script
对象:
const script = new vm.Script('returnValue = function_()');
vm.Script()
接收一个字符串,这个字符串就是即将要在 vm 中运行的代码,具体到上面这个例子,就是要在 vm 执行 returnValue = function_()
这段代码,即把 function_()
返回的结果赋值给 returnValue
变量。
那 function_
是什么东东?它是在哪里被定义的?
function_
是定义在 vm 的 context 中的,context
是一个重要概念,它本身就是 Node.js 的重要概念,所以也是 vm 的重要概念。
All JavaScript executed within Node.js runs within the scope of a "context".
写一个 context 对象,在这个 context 中定义 script 需要用到的变量,这里只有 function_
:
const context = {
function_: () => function_(...arguments_),
};
然后执行 script,runInNewContext
意思是在新的 context 中执行代码,但需要告诉它 context 是哪个,另外正如开头所说的,它支持传入超时时间:
script.runInNewContext(context, {timeout});
如果执行超时,Node.js 会抛出 ERR_SCRIPT_EXECUTION_TIMEOUT
错误码。
那怎么获得 returnValue
的值呢?returnValue
也是通过 context 获取:
context.returnValue;