简体   繁体   中英

In Node.js, how can I return a Promise from vm2?

I have some asynchronous JavaScript code, which I'd like to run using vm2 / NodeVM.

The code tests two functions: a user-submitted function evenAndOdd and a pre-defined function solution using Node's built-in assert library.

My question is, how can I get the my resolved Promise out of vm.run() ?

The Aynchronous Code

This is the test code I want to turn into a string and run using 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);
          };
        })
    }
  })
}

If I append the following code, I get exactly what I want logged to the console:

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

The vm Code

My question is, how do I get the resolved promise from 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');

Right now, the result variable above is undefined.

NodeVM.run() executes the code and returns the module created by the execution, which can then be accessed by the host code. In order to access the result of the computation in the processed code, you should assign it to module.exports .

Consider the following example:

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));

The variable vmExports holds the module exported by the run call, and the field vmExports.pr holds the promise produced by the sandboxed script. The exported promise is thenable or can be awaited to access the resolved values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM