Skip to content

Instantly share code, notes, and snippets.

@savelichalex
Last active October 8, 2015 19:21
Show Gist options
  • Save savelichalex/c1fbc1f4a8b75ee0a278 to your computer and use it in GitHub Desktop.
Save savelichalex/c1fbc1f4a8b75ee0a278 to your computer and use it in GitHub Desktop.
channels
var chan = function () {
return [];
};
var toString = Object.prototype.toString;
function go( machine, chan ) {
var gen = machine( chan );
_go( gen, gen.next() );
}
function _go( machine, step ) {
while ( !step.done ) {
if( toString.call( step.value ) === "[object Function]" ) {
var arr = step.value();
var state = arr[0];
var value = arr[1];
switch( state ) {
case "park": setImmediate( function() { _go( machine, step ); } ); return;
case "continue": step = machine.next( value ); break;
}
} else if ( toString.call( step.value ) === "[object Object]" ) { //must be "[object Promise]"
step.value.then( function ( value ) {
_go( machine, machine.next( value ) );
} );
setImmediate( function() { _go( machine, step ); } ); return;
} else {
console.log( toString.call( step.value ) );
throw Error('Incorrect yield');
}
}
}
function put( chan, value ) {
return function() {
if( chan.length === 0 ) {
chan.unshift( value );
return [ "continue", null ];
} else {
return [ "park", null ]
}
}
}
function take( chan ) {
return function() {
if( chan.length == 0 ) {
return [ "park", null ];
} else {
return [ "continue", chan.pop() ];
}
}
}
var ch = chan();
go(function* ( ch ) {
var i = 0;
for( ; i < 10; i++ ) {
yield put( ch, i );
}
var val = yield new Promise( function ( resolve ) {
setTimeout( function () {
resolve( 'Hello from promise!' );
}, 1000 );
} );
yield put( ch, val );
yield put( ch, 'And again in channel!' );
yield put( ch, null );
}, ch);
go(function* ( ch ) {
var value;
while( ( value = yield take( ch ) ) !== null ) {
console.log( 'Take: ', value );
}
}, ch);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment