await for evaluation of async module
JavaScript includes a setTimeout function: yes Functions are a type of primitive value in JavaScript: yes Objects can be shared between isolates: no
Is there a way to wait for an async module to execute?
import ivm from "isolated-vm";
const isolate = new ivm.Isolate();
const context = await isolate.createContext();
const module = await isolate.compileModule(/* language=javascript */ `
export const x = 10;
await new Promise(resolve => globalThis.hook = resolve);
export const y = 20;
`);
await module.instantiate(context, () => null);
const moduleEvalPromise = module.evaluate({promise: true, reference: true, timeout: 10});
const hook = await context.global.get("hook");
setTimeout(hook, 100);
moduleEvalPromise.then(async (moduleValue) => {
console.log("Module evaluated", moduleValue);
console.log("Value-X", await module.namespace.get("x"));
console.log("Value-Y", await module.namespace.get("y")); // error
});
I get an error when accessing variable y
Module evaluated undefined
Value-X 10
node:internal/process/promises:394
triggerUncaughtException(err, true /* fromPromise */);
^
ReferenceError: y is not defined
at (<isolated-vm boundary>)
at main.mjs:18:51
But this code wotks fine:
moduleEvalPromise.then(async (moduleValue) => {
console.log("Module evaluated", moduleValue); // undefined
setTimeout(async () => {
console.log("Value-X", await module.namespace.get("x"));
console.log("Value-Y", await module.namespace.get("y"));
}, 200); // wait longer
});
I think async module.evaluate resolves before the module is executed.
Is it possible to get Promise or callback when the module will be executed to the end?
v8 and JavaScript added top-level await after the implementation in isolated-vm, so this is probably just a limitation of the current implementation. I've been working on a rewrite but obviously that won't help you now, since that won't be ready for quite some time. You can probably work around it today by injecting a promise resolution at the end of the module and waiting on that instead.