coroutiner v0.3.3
Coroutiner
A convenience transformer to turn every GeneratorFunction
into a Promise.coroutine
.
coroutiner = require('coroutiner')
obj = {
fn: function*() {
yield Promise.delay(500)
return new Promise(function(resolve) { resolve(1000) })
}
normalFn: function() { return 5 }
}
coroutiner( obj )
obj.fn().then(function(number) {
number // returns 1000
})
Promise.coroutine(function*() {
yield obj.fn() // returns 1000
}
obj.normalFn() // returns 5
Why?
Instead of calling Promise.coroutine
on every generator function, just call coroutiner on a parent object. This allows one to build an application utilizing yield
much more conveniently when every generator is already promisified.
Just be careful what you run this over. When prototype: true
(default) is enabled this will work on class (){}.prototype
, function(){}.prototype
and {}.__proto__
, which includes instances of classes.
You can also do it recursively.
// Create a new coroutiner, which also enumerates over a functions prototype
coroutiner = require('coroutiner')
fn = function*() {}
fn.prop = 1
obj = {
fn: fn
anArray: [
{
fn: function*(){} // coroutined, due to { array: true }
}
]
klass: class Class {
fn: function*() {} // coroutined, due to { prototype: true }
}
}
// This is run on every matched GeneratorFunction
// Returning `false` will skip it from being transformed
validatorFunction = function(key, value, parent) {
if ( key.match(/idontwantyou/) ) {
return false // skipping
}
}
coroutiner.all(obj, validatorFunction)
// Properties of GeneratorFunctions will be copied over
obj.fn.prop // returns 1
Caveats and Warnings
Coroutiner will behave weirdly in this CoffeeScript example
class Test
fn: =>
# A bound function!
yield return
class NewTest extends Test
newFn: -> yield return
test = new NewTest()
coroutiner { test, NewTest }
yield test.fn() # Error, because .fn() never got coroutined before being extended
yield test.newFn() # Works because it was defined in NewTest's prototype
yield new NewTest().fn() # Works because the instance was created with the coroutined prototype
The transformer
Make sure require('bluebird')
works if you aren't specifying your own transformer. Bluebird's Promise.coroutine
is used as a transformer by default, but by creating your own coroutiner instance that can change.
coroutiner( obj, ?validatorFn?, ?types? )
Returned by require('coroutiner')
.
Transforms GeneratorFunctions
within the obj with the transformer. Will also enumerate over the fn.prototype
if prototypes are enabled.
This is not recursive.
coroutiner.all( obj, ?validator?, ?depth?, ?types? )
Recursively transforms properties, like coroutiner()
.
Be careful with this. Only run it over an object that exposes your generators. If this touches a library that expects generators then things will break.
coroutiner.Coroutiner( options )
Creates a new coroutiner instance.
options {Object}
validator {Function}
A default validator functiontransformer {Function}
A default transformer instead ofPromise.coroutine
array {Boolean} true
Whether to iterate over arrays itemsobject {Boolean} true
Whether to iterate over object propertiesfunction {Boolean} true
Whether to iterate over function propertiesprototype {Boolean} true
Whether to iterate over function/object prototypes
This controls which properties are enumerated over to look for transformable properties.
coroutiner.create( fn, ?types? )
Create a coroutined function and copies over its properties into a new returned function.
This is called by coroutiner()
and coroutiner.all()
coroutiner.types
{
object: true, function: true, array: true
prototype: true, unowned: true, circular: false
}
unowned
as false
if you only want .hasOwnProperty
properties
circular
as true
will remove cyclic recursion protection
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago