【问题标题】:In Node.js, how can I return a Promise from vm2?在 Node.js 中,如何从 vm2 返回 Promise?
【发布时间】:2019-08-07 10:55:17
【问题描述】:

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

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

我的问题是,我如何才能从vm.run() 中获得已解决的 Promise?

异步代码

这是我想转成字符串并使用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 变量是未定义的。

【问题讨论】:

    标签: javascript node.js assert node-vm2


    【解决方案1】:

    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。导出的 Promise 是 thenable 或可以等待访问已解析的值。

    【讨论】:

      猜你喜欢
      • 2015-03-04
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 2017-12-20
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      相关资源
      最近更新 更多