Skip to content

Instantly share code, notes, and snippets.

@ernestlv
Last active April 27, 2016 22:56
Show Gist options
  • Save ernestlv/68166925b46c7febc3087e2749fa9966 to your computer and use it in GitHub Desktop.
Save ernestlv/68166925b46c7febc3087e2749fa9966 to your computer and use it in GitHub Desktop.
ES7: Executes functions asynchronously using promises and generators.
//invokes segments of an asynchronus function
function asyncF(generator) {
try {
var steps = generator(); // function to exec by segments
return iterate(steps.next());
} catch(e) {
return Promise.reject(e); // rejects iteration
}
function iterate({value, done}) { // arg has value of prev iteration
if (done) return Promise.resolve(value); // resolves all pending promises
// make sure we have a promise and when resolved do another iteration
// or iterator.throw rejects all pending promises
return Promise.resolve(value).then( v => iterate(steps.next(v))).catch(e => steps.throw(e));
}
}
promise = v => (new Promise(r => setTimeout( x => r(v), ((Math.random() * (10 - 1)) + 1 | 0) * 1000)));
console.log('print first');
asyncF(function* () {
console.log(new Date(), yield promise(1)); //awaits for promise to resolve without blocking JS
console.log(new Date(), yield promise(2));
console.log(new Date(), yield promise(3));
console.log(new Date(), yield promise(4));
console.log(new Date(), yield promise(5));
console.log(new Date(), yield promise(6));
return 'last';
}).then(v => console.log(v), e => console.log(e)); //this prints 'last' or error
console.log('print second'); //executes immediatly since asyncFunc does not block JS
//or a compac version using a loop
asyncF(function* () {
for(var i=1; i<6; i++){
console.log(new Date(), yield promise(i))
}
});
//or using a map to execute all promises in parallel!
asyncF(function* () {
for (var p of [1,2,3,4,5,6].map(promise)){
console.log(new Date(), yield p)
}
});
@ernestlv
Copy link
Author

ernestlv commented Apr 24, 2016

@ernestlv
Copy link
Author

ernestlv commented Apr 24, 2016

//exec segments in a loop
asyncF(function* () {
for(var i=1; i<4; i++){
console.log( yield promise(i) ); //halts loop
console.log( yield promise(++i) ); //continues loop
}
console.log("done", i) //exec last
});

@ernestlv
Copy link
Author

//Example:

function* (){
var customers = yield getCustomers('http://api.mycompany.com/customer'); //stops till customers is ready
var policies = customers.map(getPolicies); //gets all policies in parallel
for (policy in policies){
printReport(customers, yield policy); //prints policies sequencially
}
return 'done';
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment