Skip to content

Instantly share code, notes, and snippets.

@depeele
Last active December 14, 2015 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save depeele/5107544 to your computer and use it in GitHub Desktop.
Save depeele/5107544 to your computer and use it in GitHub Desktop.
A small example of progress chaining using node.js and https://github.com/cujojs/when
var When = require('when');
/*******************************************************
* Define a class with asynchronous methods
*
*/
function Test() { return this.init(); }
Test.prototype = {
init: function() {
var self = this;
self._ready = When.defer();
self.ready = self._ready.promise;
// Simiulate initialization that takes time
var ticks = 2,
tick = 0,
timer = setInterval(function() {
if (++tick === ticks)
{
clearInterval(timer);
self._ready.notify('Test: Ready @ '
+ tick +' / '+ ticks);
self._ready.resolve('Ready');
return;
}
self._ready.notify('Test: '+ tick +' / '+ ticks);
}, 100);
return self;
},
get: function() {
var self = this,
defer = When.defer();
/* Simiulate a method that takes time and then invokes a closure that
* depends on two others
*/
var ticks = 5,
tick = 0,
timer = setInterval(function() {
if (++tick === ticks)
{
clearInterval(timer);
defer.notify('Test.get(): invoke __one @ '
+ tick +' / '+ ticks);
__one()
.then(function(val) {
return defer.resolve('Test.get.'+ val);
},
defer.reject, defer.notify);
return;
}
defer.notify('Test.get(): '+ tick +' / '+ ticks);
}, 1);
return defer.promise;
/*******************************************
* Context-bound helpers
*
*/
function __one() {
var defer1 = When.defer(),
pending = [];
// This closure depends on two others
pending.push( __two() );
pending.push( __three() );
When.all(pending,
function(val) {
return defer1.resolve('__one.'+ val.join('.'));
},
defer1.reject, defer1.notify);
return defer1.promise;
}
function __two() {
var defer2 = When.defer();
// This portion of the chain takes time...
var ticks = 5,
tick = 0,
timer = setInterval(function() {
if (++tick === ticks)
{
clearInterval(timer);
defer2.notify('Test.get.__two(): complete @ '
+ tick +' / '+ ticks);
return defer2.resolve('__two');
}
defer2.notify('Test.get.__two(): '
+ tick +' / '+ ticks);
}, 100);
//defer2.reject('__two: error');
return defer2.promise;
}
function __three() {
var defer3 = When.defer();
// This portion of the chain takes even more time...
var ticks = 10,
tick = 0,
timer = setInterval(function() {
if (++tick === ticks)
{
clearInterval(timer);
defer3.notify('Test.get.__three(): complete @ '
+ tick +' / '+ ticks);
return defer3.resolve('__three');
}
defer3.notify('Test.get.__three(): '
+ tick +' / '+ ticks);
}, 100);
return defer3.promise;
}
}
};
/*******************************************************
* Make use of the asynchronous class
*
*/
var test = new Test();
test.ready
.then(function(val) {
console.log("test.ready:resolved(): %j", val);
test.get()
.then(function(val) {
console.log("test.get:resolved(): %j", val);
},
function(err) {
console.log("test.get:rejected(): %s", err);
},
function(data) {
console.log("test.get:notify(): %j", data);
});
},
function(err) {
console.log("test.ready:rejected(): %s", err);
},
function(data) {
console.log("test.ready:notify(): %j", data);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment