I cannot find a script that cannot be solved with node-fibers. The example you provided with node-fibers behaves as expected. The key is to run all the relevant code inside the fiber, so you do not need to start a new fiber in random positions.
Let's look at an example: Suppose you use some framework that is the entry point of your application (you cannot change this structure). This structure loads nodejs modules as plugins and calls some methods for plugins. Suppose that this structure allows only synchronous functions and does not use fibers itself.
There is a library that you want to use in one of your plugins, but this library is asynchronous, and you also do not want to change it.
The main thread cannot be obtained if no fiber is working, but you can still create plugins using the fibers! Just create a wrapper record that runs the entire structure inside the fiber so you can execute from plugins.
Downside: If an infrastructure uses setTimeout or Promise internally, it will exit the fiber context. This can be circumvented by mocking setTimeout , Promise.then and all event handlers.
This way you can get the fiber until Promise is allowed. This code accepts the async (Promise return) function and resumes the fiber when the promise is resolved:
framework-entry.js
console.log(require("./my-plugin").run());
asynchronous-lib.js
exports.getValueAsync = () => { return new Promise(resolve => { setTimeout(() => { resolve("Async Value"); }, 100); }); };
my-plugin.js
const Fiber = require("fibers"); function fiberWaitFor(promiseOrValue) { var fiber = Fiber.current, error, value; Promise.resolve(promiseOrValue).then(v => { error = false; value = v; fiber.run(); }, e => { error = true; value = e; fiber.run(); }); Fiber.yield(); if (error) { throw value; } else { return value; } } const asyncLib = require("./async-lib"); exports.run = () => { return fiberWaitFor(asyncLib.getValueAsync()); };
my-entry.js
require("fibers")(() => { require("./framework-entry"); }).run();
When starting node framework-entry.js it throws an error: Error: yield() called with no fiber running . If you run node my-entry.js , it works as expected.
Tamas Hegedus Jul 14 '16 at 14:26 2016-07-14 14:26
source share