首页 > 解决方案 > 在 Node.js 中,如何从 vm2 返回 Promise?

问题描述

我有一些异步 JavaScript 代码,我想使用 vm2 / NodeVM 运行它们。

该代码测试两个函数:一个用户提交的函数和一个使用 Node 内置库evenAndOdd的预定义函数。solutionassert

我的问题是,我怎样才能得到我已解决的承诺vm.run()

异步代码

这是我想变成字符串并运行的测试代码vm2

const assert = require('assert');

function evenAndOdd(arr) {
  return [arr.filter(el => el % 2 === 0).sort(), arr.filter(el => el % 2 === 1).sort()];
};

function solution(arr) {
  return [arr.filter(el => el % 2 === 0).sort(), arr.filter(el => el % 2 === 1).sort()];
};

const runTest = async () => {

  return new Promise((resolve, reject) => {

    const map = new Map();
    const tests = 10;

    for (let i = 0; i < tests; i++) {

      let randLength = parseInt(Math.random() * 19 + 1);
      let randArray = [...Array(randLength)].map(e => ~~(Math.random() * randLength));

      const test = async () => {
        return assert.deepEqual(evenAndOdd(randArray), solution(randArray));
      }

      const description = "TEST CASE: evenAndOdd([" + randArray + "}]) EXPECT: [[" + solution(randArray)[0] + "], [" + solution(randArray)[1] + "]] GOT: [[" + evenAndOdd(randArray)[0] + "], [" + evenAndOdd(randArray)[1] + "]]";

      test()
        .then(() => {
          map.set(description, true);
          if (map.size === tests) {
            resolve(map);
          };
        })
        .catch(() => {
          map.set(description, false);
          if (map.size === tests) {
            resolve(map);
          };
        })
    }
  })
}

如果我附加以下代码,我会得到我想要记录到控制台的内容:

runTest().then((result) => {
  console.log(result)
});

vm守则_

我的问题是,我如何获得已解决的承诺vm.run()

const { NodeVM } = require('vm2');

  const vm = new NodeVM({
    console: 'inherit',
    sandbox: {},
    require: {
      external: true,
      builtin: ['assert'],
      import: ['assert'],
      root: "./",
    },
  });

const result = vm.run(stringifiedJavaScript, 'vm.js');

现在,result上面的变量是未定义的。

标签: javascriptnode.jsassertnode-vm2

解决方案


NodeVM.run()执行代码并返回执行创建的模块,然后主机代码可以访问该模块。为了访问已处理代码中的计算结果,您应该将其分配给module.exports.

考虑以下示例:

const {NodeVM} = require("vm2");
const vm = new NodeVM();

const vmExports = vm.run('module.exports.pr = Promise.resolve(42);');

vmExports.pr.then(x => console.log(x));

变量vmExports保存调用导出的模块run,字段vmExports.pr保存沙盒脚本生成的承诺。导出的 Promise 是可以的,或者可以等待访问解析的值。


推荐阅读