Skip to content

Instantly share code, notes, and snippets.

@milankinen
Last active November 13, 2018 23:29
Show Gist options
  • Save milankinen/ea747711890212c80f369041145b9910 to your computer and use it in GitHub Desktop.
Save milankinen/ea747711890212c80f369041145b9910 to your computer and use it in GitHub Desktop.
Sync promise resolution with fibers (tested with Node v11.1.0)
const vm = require("vm");
const { resolve, run } = require("./sync");
// in "master"
const calls = [];
const log = console.log.bind(console);
const random = Math.random;
// in "worker"
const callFromMaster = (name, args) =>
new Promise((pResolve, pReject) => {
// timeout simulates "async IPC"
setTimeout(() => {
try {
calls.push([name, args]);
pResolve(
(() => {
switch (name) {
case "console.log":
return log(...args);
case "Math.random":
return random();
}
})()
);
} catch (e) {
pReject(e);
}
}, 1000);
});
const notifyMasterThatTestEnded = () => {
// collect the results in "master"
console.log("CALLS", calls);
};
const stubCall = name => (...args) => {
return resolve(callFromMaster(name, args));
};
const stubs = {
console: {
...console,
log: stubCall("console.log")
},
Math: { ...Math, random: stubCall("Math.random") }
};
run(() => {
// ... running the tested script ...
const code = `
console.log("Before");
console.log("Random:", Math.random());
console.log("After");
`;
vm.createContext(stubs);
vm.runInContext(code, stubs);
}).then(notifyMasterThatTestEnded);
// npm i --save fibers
const Fiber = require("fibers");
const Future = require("fibers/future");
const Fiber = require("fibers");
const Future = require("fibers/future");
module.exports = {
resolve(promise) {
if (!promise instanceof Promise) {
throw new TypeError("Only promises supported");
}
const f = new Future();
promise.then(res => f.return(res), err => f.throw(err));
return f.wait();
},
run(f) {
return new Promise(resolve => {
Fiber(() => {
f();
resolve();
}).run();
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment