我在使用 runInNewContext
执行代码时遇到vm
问题。
自定义代码可以返回一个承诺,该承诺可能是嵌套的,并且可以具有嵌套的调用堆栈。代码如下所示
function executeInSandbox(code, sandbox){
return Async((code, _sandbox) => {
let fn = `"use strict";
this.result = async(() => {
${code}
})();`;
var script = new vm.Script(fn);
return Await(
script.runInNewContext(_sandbox, {
displayErrors: true,
timeout: 30000
})
);
})(code, sandbox);
};
result = Await(executeInSandbox(code, sandbox))
现在的问题是,如果承诺的时间超过 20 秒,我想停止处理承诺。
如果代码是递归的并且带有嵌套的承诺,它就会在 20Sec 内堆叠,但现在尝试执行调用堆栈,这需要几分钟多的时间并且不可停止,最后,会出现堆栈溢出问题。
我尝试以下添加Promise.race
let timeout = new Promise((resolve, reject) => {
let id = setTimeout(() => {
clearTimeout(id);
reject('Timed out in '+ 2000 + 'ms.')
}, 2000);
});
let fn = `"use strict";
this.result = async(() => {
${code}
})();`;
var script = new vm.Script(fn);
let codePromise = script.runInNewContext(_sandbox, {
displayErrors: true,
timeout: 30000
});
return Await(
Promise.race([
codePromise,
timeout
])
);
})(code, sandbox);
它的工作方式是将控件排除在函数之外,但是,承诺链一直在执行。
有没有办法停止codePromise
? 或 Await 中的超时?
20 秒超时视为代码的主要功能。 所有承诺必须解决或拒绝。 如果函数需要超时,则必须通过解析或拒绝来实现超时。 不要以为你可以在外部强制这样做。
babel
的transformFromAst
使用代码注入解决。
只需在每个函数声明和函数表达式的开头执行时间超过指定的时间跨度,只需throw error
即可。