Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Latest commit

History

100 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Deprecation Notice

As of this notice, the node-sync project has been archived and will no longer receive maintenance or updates. I want to express my gratitude to the entire community for your usage and contributions.

Introduction

node-sync is a simple library that allows you to call any asynchronous function in synchronous way. The main benefit is that it uses javascript-native design - Function.prototype.sync function, instead of heavy APIs which you'll need to learn. Also, asynchronous function which was called synchronously through node-sync doesn't blocks the whole process - it blocks only current thread!

It built on node-fibers library as a multithreading solution.

Examples

Simply call asynchronous function synchronously:

varSync=require('sync');functionasyncFunction(a,b,callback){process.nextTick(function(){callback(null,a+b);})}// Run in a fiberSync(function(){// Function.prototype.sync() interface is same as Function.prototype.call() - first argument is 'this' contextvarresult=asyncFunction.sync(null,2,3);console.log(result);// 5// Read file synchronously without blocking whole process? no problemvarsource=require('fs').readFile.sync(null,__filename);console.log(String(source));// prints the source of this example itself})

It throws exceptions!

varSync=require('sync');functionasyncFunction(a,b,callback){process.nextTick(function(){callback('something went wrong');})}// Run in a fiberSync(function(){try{varresult=asyncFunction.sync(null,2,3);}catch(e){console.error(e);// something went wrong}})// Or simply specify callback function for Sync fiber// handy when you use Sync in asynchronous environmentSync(function(){// The result will be passed to a Sync callbackvarresult=asyncFunction.sync(null,2,3);returnresult;},function(err,result){// <-- standard callbackif(err)console.error(err);// something went wrong// The result which was returned from Sync body functionconsole.log(result);})

Transparent integration

varSync=require('sync');varMyNewFunctionThatUsesFibers=function(a,b){// <-- no callback here// we can use yield here// yield();// or throw an exception!// throw new Error('something went wrong');// or even sleep// Sync.sleep(200);// or turn fs.readFile to non-blocking synchronous function// var source = require('fs').readFile.sync(null, __filename)returna+b;// just return a value}.async()// <-- here we make this function friendly with async environment// Classic asynchronous nodejs environmentvarMyOldFashoinAppFunction=function(){// We just use our MyNewFunctionThatUsesFibers normally, in a callback-driven wayMyNewFunctionThatUsesFibers(2,3,function(err,result){// If MyNewFunctionThatUsesFibers will throw an exception, it will go hereif(err)returnconsole.error(err);// 'return' value of MyNewFunctionThatUsesFibersconsole.log(result);// 5})}// From fiber environmentSync(function(){// Run MyNewFunctionThatUsesFibers synchronouslyvarresult=MyNewFunctionThatUsesFibers(2,3);console.log(result);// 5// Or use sync() for it (same behavior)varresult=MyNewFunctionThatUsesFibers.sync(null,2,3);console.log(result);// 5})

Parallel execution:

varSync=require('sync'),Future=Sync.Future();// Run in a fiberSync(function(){try{// Three function calls in parallelvarfoo=asyncFunction.future(null,2,3);varbar=asyncFunction.future(null,5,5);varbaz=asyncFunction.future(null,10,10);// We are immediately here, no blocking// foo, bar, baz - our tickets to the future!console.log(foo);// { [Function: Future] result: [Getter], error: [Getter] }// Get the results// (when you touch 'result' getter, it blocks until result would be returned)console.log(foo.result,bar.result,baz.result);// 5 10 20// Or you can straightly use Sync.Future without wrapper// This call doesn't blocksasyncFunction(2,3,foo=Future());// foo is a ticketconsole.log(foo);// { [Function: Future] result: [Getter], error: [Getter] }// Wait for the resultconsole.log(foo.result);// 5}catch(e){// If some of async functions returned an error to a callback// it will be thrown as exceptionconsole.error(e);}})

Timeouts support

varSync=require('sync'),Future=Sync.Future;functionasyncFunction(a,b,callback){setTimeout(function(){callback(null,a+b);},1000)}// Run in a fiberSync(function(){// asyncFunction returns the result after 1000 msvarfoo=asyncFunction.future(null,2,3);// but we can wait only 500ms!foo.timeout=500;try{varresult=foo.result;}catch(e){console.error(e);// Future function timed out at 500 ms}// Same example with straight future functionasyncFunction(2,3,foo=newFuture(500));try{varresult=foo.result;}catch(e){console.error(e);// Future function timed out at 500 ms}})

How to address non-uniform callbacks

Sometimes third-party libraries are not following convention and passing multiple result parameters to the callback, e.g. callback(err, recordsets, returnValue). In this situation, node-sync will simply return array of values instead of value.

// Asynchronous which returns multiple arguments to a callback and returning a value synchronouslyfunctionasyncFunctionReturningMultipleArguments(callback){process.nextTick(function(){callback(null,2,3);})}Sync(function(){varresult=asyncFunctionReturningMultipleArguments.sync();assert.equal(result,[2,3]);})

See more examples in examples directory.

Installation

install

$ npm install sync

and then

$ node your_file_using_sync.js

About

Write simple and readable synchronous code in nodejs using fibers

Resources

Stars

494 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages