Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

using asynquence's `runner(..)` plugin to do async CSP-style (message-passing) generator co-routines

View gist:10172207
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
// just a silly number generator that's promise-async
function getVal() {
return new Promise( function(resolve,reject){
setTimeout( function(){
if (!getVal.__number) getVal.__number = 0;
resolve( getVal.__number += 10 );
}, 100 );
} );
}
 
// **********************
 
ASQ( 2, 3 )
.runner(
// machine 1
function*(token){
token.messages; // [2, 3]
 
token.messages[0] += yield getVal(); // pauses generator while promise resolves
token.messages[1] += yield getVal(); // pauses generator while promise resolves
token.messages.push( token.messages[0] + token.messages[1] );
 
token.messages; // [12, 23, 35]
 
yield token; // hand control over to next machine
 
token.messages; // [ 100 ]
 
token.messages[0] += yield getVal(); // pauses generator while promise resolves
 
// implicit finish means transfer control to next machine
},
// machine 2
function*(token){
token.messages; // [12, 23, 35]
 
token.messages = [ token.messages[0] + token.messages[1] + token.messages[2] ];
token.messages; // [ 70 ]
 
token.messages[0] += yield getVal(); // pauses generator while promise resolves
token.messages; // [ 100 ]
 
yield token; // hand control over to next machine
 
token.messages; // [ 140 ]
 
token.messages.push( "Hello World" );
 
yield token.messages;
}
)
.val( function(msgs){
console.log( msgs[0], msgs[1] ); // 140 "Hello World"
} );
Taytay commented

This is awesome. I would love to see a direct translation into non ES6 code. I get the "substitute yield token" for "return token", but don't quite have my head wrapped around how I would structure machine1 and machine2 as sequences instead of ES6 generators.

Taytay commented

Actually, I got it working after all. I don't know if this is an idiomatic translation, but it gets the job done.
This is written in typescript, so there is some extra type fluff that you can (hopefully) ignore.

I was particularly curious what the best way was to translate token.messages[0] += yield getVal();
I ended up with:

            .then((theToken:any)=> {
                token = theToken;
                return getVal();
            })
            .then((value:any)=>{
                token.messages[0]+= value;
...

Not sure if that's the cleanest or best way to do this.

Here's the full code:

it("Can pass messages back and forth between two routines, just like another gist", function (testDone) {
    //just a silly number generator that's promise-async
    function getVal() {
        return new Promise( function(resolve,reject){
            setTimeout( function(){
                if (!(<any>getVal).__number) (<any>getVal).__number = 0;
                resolve( (<any>getVal).__number += 10 );
            }, 100 );
        } );
    }


    var machine1 = function(){
        var token : any = null;
        return ASQ.iterable()
            .then((theToken:any)=> {
                token = theToken;
                return getVal();
            })
            .then((value:any)=>{
                token.messages[0]+= value;
                return getVal();
            })
            .then((value:any)=>{
                token.messages[1]+= value;
                token.messages.push( token.messages[0] + token.messages[1] );
                return token;
            })
            .then(()=>{
                return getVal();
            })
            .then((value:number)=>{
                token.messages[0] += value;
            })
    }

    var machine2 = function(){
        var token : any = null;
        return ASQ.iterable()
            .then((theToken:any)=> {
                token = theToken;
                token.messages = [ token.messages[0] + token.messages[1] + token.messages[2] ];
                return getVal();
            })
            .then((value:any)=>{
                token.messages[0] += value;
                return token;
            })
            .then(()=>{
                token.messages.push( "Hello World" );
                return token.messages;
            })

    }


    ASQ( 2, 3 )
        .runner(
        machine1(),
        machine2()
    )
        .val( function(msgs){
            console.log( msgs[0], msgs[1] ); // 140 "Hello World"
            expect(msgs[0]).to.equal(140);
            expect(msgs[1]).to.equal("Hello World");
            testDone();
        } )
        .catch((e:Error)=>{
            testDone(e)}
    );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.