wait.for(fs.readfile,'/etc/passwd') == fs.readfileSync('/etc/passwd')
wait.for allows you to call any async function as if it were a sync function, without blocking node's event loop. It works inside a fiber. Check the examples.
function wait.for ( asyncFn, params ) {
//call the async fn, returns immediately
asyncFn(params, function(err,data){
//here the data is ready
thisFiber.err = err;
thisFiber.data = data;
thisFiber.resume(); //resume execution (after yield())
});
//we're in a fiber, so we can yield() to node's event loop
thisFiber.yield(); //pause here, give back control to node's event loop
// the next line will be executed when thisFiber.resume() is called
if (thisFiber.err) throw thisFiber.err; // throw into the caller of wait.for
return thisFiber.data; //ok
}You don't have to wrap all your code in a call to `Fiber()`
full classic node-server sample:
var http=require('http'), wait=require('wait.for');
http.createServer(function(req, res) {
wait.launchFiber(handleRequest,req, res); //run in a Fiber, keep node spinning
}).listen(8080);
//in a fiber
function handleRequest(req, res) {
try {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(
"<h1>Demo page</h1>"
+ "<p>"+ wait.for(fs.readFile,'/etc/somefile') +"</p>"
+ "<p>"+ wait.for(fs.readFile,'/etc/otherfile') +"</p>");
}
catch(err) {
res.end('error '+e.message);
}
}That is probably a worthwhile tradeoff, but the first time I read through it, that mechanic wasn't obvious to me.
Today launchFiber is calling the fn inside a Fiber(), tomorrow could be launching the fiber by means of a generator.
The idea was to create a very simple abstraction to avoid callback hell, adding low or no complexity, and keeping the flexibility to use all the existing async fns with a callback or just "wait" for the results.
the code is here: https://github.com/luciotato/waitfor/blob/master/waitfor.js, but it does require fibers.