暂停promise链或停止runInNewContext返回promise链

时间:2018-01-02 15:31:39

标签: node.js promise nodevm

我在使用vm执行代码时遇到runInNewContext的问题。

自定义代码可以返回可能嵌套的promise,并且可以具有嵌套的调用堆栈。代码如下所示

 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秒,我想暂停对promise的处理。

如果代码是递归的并且使用嵌套的promises,它会被堆叠并且在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);

它的作用是将控件从函数中移除,但是,promise链不断执行。

有办法停止codePromise吗?或在Await中超时?

2 个答案:

答案 0 :(得分:0)

您需要将20秒超时视为代码的主要功能。所有承诺必须解决或拒绝。如果函数需要超时,则必须通过解析或拒绝来执行此操作。不要以为你可以在外部强制这样做。

答案 1 :(得分:0)

目前通过babel的{​​{1}}使用代码注入解决了这个问题。

如果执行时间超过每个函数声明和函数表达式开头的指定时间间隔,则只需transformFromAst