Last active
August 29, 2015 14:01
-
-
Save trxcllnt/f2a8d4d2fc50cd7da586 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Zone.create = Observable.create | |
// Zone#setCallback = Observable#forEach/Observable#subscribe | |
// Zone#then = Observable#map | |
// Zone#catch = Observable#catch | |
// | |
// A little stub of some zone examples that map 1-1 with Rx. Instead of a zone global, | |
// the "zone" object is passed in to the function we created the Zone with. | |
// | |
// This allows us to run multiple Zones in parallel, for example, if we want to await | |
// two run two asynchronous operations (say, a file-read and a network request) at the | |
// same time, then call the return callback when they're both done. | |
// | |
// Additionally, since Zone has a "complete" callback, a Zone itself can be thought of as | |
// an asynchronous collection of return values, or a long-running function with multiple | |
// return values. | |
// | |
// Disclaimer: I've spent about five minutes reading the "why-zone", description, and examples. | |
// I am sure I have missed very large, important points. But from the docs, it sounds like | |
// Reactive Extensions might be able to do everything you're trying to do, and it's been | |
// through six years of iteration by some of the best computer scientists on the planet. | |
// https://github.com/Reactive-Extensions/RxJS/ | |
var readFileZone = Zone.create(function(zone) { | |
fs.readFile(function(err, x) { | |
if(err) { | |
zone.throw(err); | |
zone.complete(); | |
} else { | |
zone.return(x); | |
} | |
}); | |
}); | |
readFileZone.setCallback({ | |
return: function(x) { | |
console.log('yay I read my file.'); | |
}, | |
throw: function(err) { | |
console.error('error', err); | |
}, | |
complete: function() { | |
console.log('all done'); | |
} | |
}); | |
var intervalZone = Zone.create(function(zone) { | |
var i = -1, | |
t = setInterval(function() { | |
zone.return(++i); | |
if(i > 9) { | |
clearInterval(t); | |
zone.complete(); | |
} | |
}, 100); | |
}); | |
intervalZone.setCallback({ | |
return: function(i) { | |
console.log('got interval', i); | |
}, | |
throw: function(e) { | |
console.error('what?'); | |
}, | |
complete: function() { | |
console.log('all done'); | |
} | |
}); | |
var numbers = [ | |
'zero', 'one', 'two', | |
'three', 'four', 'five', | |
'six', 'seven', 'eight', | |
'nine', 'ten' | |
]; | |
// This Zone starts its own separate `setInterval` context than | |
// the previous time we called `intervalZone.setCallback()` | |
var printIntervalZone = intervalZone.then(function(i) { | |
return numbers[i]; | |
}); | |
// call then's `setCallback,` which calls the intervalZone's `setCallback` | |
printIntervalZone.setCallback({ | |
return: function(number) { | |
console.log('got number', number); | |
}, | |
throw: function(e) { | |
console.error('nah'); | |
}, | |
complete: function() { | |
console.log('all done'); | |
} | |
}) | |
function Zone(setCallback) { | |
this.setCallback = setCallback; | |
} | |
Zone.create = function(setCallback) { | |
return new Zone(setCallback); | |
} | |
Zone.prototype.then = function(successCallback, errorCallback) { | |
var self = this; | |
return Zone.create(function(zone) { | |
return self.setCallback({ | |
return: function(x) { | |
zone.return(successCallback(x)); | |
}, | |
throw: function(e) { | |
if(errorCallback) { | |
try { | |
var result = errorCallback(e); | |
zone.return(result); | |
} catch(e) { | |
zone.throw(e); | |
} | |
} else { | |
zone.throw(e); | |
} | |
}, | |
complete: zone.complete.bind(zone) | |
}) | |
}); | |
}; | |
Zone.prototype.catch = function(handler) { | |
var self = this; | |
return Zone.create(function(zone) { | |
return self.setCallback({ | |
throw: function(e) { | |
try { | |
var result = handler(e); | |
zone.return(result); | |
} catch(e) { | |
zone.throw(e); | |
} | |
}, | |
return: zone.return.bind(zone), | |
complete: zone.complete.bind(zone) | |
}) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The point of zones is: this should work, and throw in an async function should not crash node.
Does rx do this?