• Stars
    star
    211
  • Rank 186,867 (Top 4 %)
  • Language
    JavaScript
  • Created over 11 years ago
  • Updated over 9 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A radically simpler way to deal with asynchronous functions in js ( deprecated. see: www.radioactivejs.org )

This project is no longer maintained. It has been merged into Radioactive JS.

Syncify.js

Syncify is an innovative alternative to Async.js, Step and Node Fibers. It allows you to deal with "Callback Hell" in a very simple way.

It works just like Node Fibers in that it completely eliminates the need for callbacks. But, unlike Node Fibers, it also works on the browser!

Syncify Intro Video

Remove All The Callbacks

Example

Without Syncify

Assume that we have a very simple async function that issues an AJAX request to some remote REST API

ajax( url, callback )

This would be a typical composite function that calls the ajax() service several times:

function getFullName( id, cb ){
  ajax( "/user/" + id + "/name", function( err, name ){
    if ( err ){
      cb( err );
    } else {
      ajax( "/user/" + id + "/lastname", function( err, lastname ){
        if ( err ){
          cb( err )
        } else {
          cb( null, name + " " + lastname )
        }
      })
    }
  })
}

Uff. That's a lot of nested callbacks. Let's see if we can do better.

With Syncify

// 1. magically remove the callback from the ajax() service
ajax = syncify( ajax )

// 2. create a composite function. but this time without callbacks
function getFullName( id ){
	return ajax( "/user/" + id + "/name" ) + " " + ajax( "/user/" + id + "/lastname" )
}

// 3. add a callback to the resulting function so we can later use it
getFullName = syncify.revert( getFullName )

Both functions ( the one with syncify and the one without syncify ) are equivalent. You can call them like this:

getFullName( "aldo", function( err, res ){ console.log( res )})

Isn't that awesome?

Syncify allowed us to magically get rid of callbacks while creating a composite function. It is not just cleaner, but it also allows us to take advantage of the full power of Javascript.

You can use any function. For example:

function getNameUC( id ){
	return ajax("/user/" + id + "/name").toUpperCase()
}

You can even process a collection using Array.map()!

function getFriendNames( id ){
	return ajax("/user/" + id + "/friends").map( function( friend ){
		return ajax("/user/" + friend + "/name" ) + " " + ajax("/user/" + friend + "/lastname" )
  })
}

Or, same as above but using the function we had already defined

function getFriendNames( id ){
	return ajax("/user/" + id + "/friends").map( getFullName )
}

You can literally do anything. Syncify allows you to escape from Callback Hell so you can continue coding in regular Javascript.

Limitations

Well. To be honest. You cannot do just anything. You cannot use Syncify to deal with functions that mutate application state. That means you can exclusively use it with read-only functions.

If this sounds like a limitation to you then I suggest you stop and think about the following: If the portion of your code that mutates state depends on a set of mutually-dependent async calls your application may be open to race conditions. My personal recommendation is to avoid all async code within transactional operations unless you know what you are doing.

Syncify is designed to make your life easier when building UIs and reading data. And if you still want to write your business logic by composing async transactions ( at the expense of integrity ) then maybe Async.js is a better tool for the job.

Concurrency

You can make the above method much faster by using syncify.parallel:

function getFriendNames( id ){
  var friends = ajax("/user/" + id + "/friends")
  syncify.parallel(function(){
    // all requests issued within this block will be parallelized
    friends.map(function(){
      return ajax("/user/" + id + "/name" ) + " " + ajax("/user/" + id + "/lastname" )
    })
  })
}

The syncify.parallel() function is explained in this video.

Quickstart

Get the code

Using NPM

npm install syncify

Load Javascript on the browser

Syncify has no external dependencies. Just include it like you would any JS library:

<script src="http://aldonline.github.io/syncify/build/syncify-1.1.0.min.js"/>

If you prefer you can find the .js and .min.js builds in the /build directory.

API

syncify( asyncFunc: Function ): Function

Takes an async function and returns a syncified version

syncify.revert( syncifiedFunc: Function ): Function

Takes a syncified function ( or a function that contains nested syncified functions ) and returns an equivalent async function ( one that takes a callback ). This function is the counterpart/opposite of syncify().

syncify.parallel( block:Function )

See video ( top of the page )

syncify.sequence( block:Function )

See video ( top of the page )

Caveats

  • Functions must be idempotent
  • Their arguments must be JSON serializable
  • There are a few known bugs ( see issue #18 ). But other than that the code has been used in a dozen apps in production for over 4 months.

More Repositories

1

node-sparql

Low level, minimal SPARQL HTTP Client for Node.JS
CoffeeScript
28
star
2

reactivity

The Unofficially Official ( Native ) Reactivity API for Javascript
JavaScript
11
star
3

fast-pyramid-generator

Python
8
star
4

raml-typescript

4
star
5

facebook-express

CoffeeScript
4
star
6

memgraph

Minimalist in-memory javascript graph
CoffeeScript
3
star
7

co.angel.scala.api

Scala wrapper for the AngelList API
Scala
3
star
8

mapochovalley.com

JavaScript
3
star
9

dbpedia-countries-extra-data

CoffeeScript
3
star
10

x-naming-convention

2
star
11

e8util

CoffeeScript
2
star
12

smartservices

Extend Java a bit to implement a low level workflow engine
Java
2
star
13

fbrs

Facebook RDF Sync
CoffeeScript
2
star
14

minirpc

Really simple Browser-->Server RPC for Node.js
JavaScript
2
star
15

opendata-cl-dpa

OpenData Chile - DPA
2
star
16

LinkedDataMate

TextMate Bundle for Linked Data Development
Ruby
1
star
17

node-virtuoso-isql-wrapper

Thin wrapper atop the OpenLink (Virtuoso) iSQL client
CoffeeScript
1
star
18

node-nativeimage

Some native routines to deal with some personal image processing needs. Not for general use.
C++
1
star
19

deepmosaicviewer

Seadragon + Mosaic layer
JavaScript
1
star
20

node-sparql-record

SPARQL + Active Record layer for Node.js
CoffeeScript
1
star
21

meteor-accounts-angellist

Meteor package for the Angel List OAuth2 API
JavaScript
1
star
22

jquery.reactivity

CoffeeScript
1
star
23

golden-progression-util

CoffeeScript
1
star
24

node-virtuoso-ini-parser

OpenLink Virtuoso(.ini) parser for Node
CoffeeScript
1
star
25

LinkedDataObjects

An Abstraction Layer Atop SPARQL to easily query/update Linked Data Graphs
1
star