Skip to content

Instantly share code, notes, and snippets.

@cbrunnkvist
Created January 20, 2016 06:41
Show Gist options
  • Save cbrunnkvist/844909c7cd7d86b54957 to your computer and use it in GitHub Desktop.
Save cbrunnkvist/844909c7cd7d86b54957 to your computer and use it in GitHub Desktop.
A verbose example of making JS/ES6 async code feel synchronous using generator/yield
'use strict';
const Promise = require('bluebird');
function someAsyncTask() {
return new Promise(function(resolve) {
let delay = Math.floor(Math.random() * 10000);
setTimeout(function () {
resolve(delay);
}, delay);
});
}
let main = Promise.coroutine(function* (sequenceName) {
console.log(sequenceName, 'starting 1st step');
let result1 = yield someAsyncTask();
console.log(sequenceName, 'starting 2nd step');
let result2 = yield someAsyncTask();
console.log(sequenceName, 'starting 3rd step');
let result3 = yield someAsyncTask();
console.log(sequenceName, 'done after', result1 + result2 + result3);
return result1 + result2 + result3;
});
main('first sequence');
main('second sequence');
console.log('all systems go!');
@vkelman
Copy link

vkelman commented Jun 2, 2016

@cbrunnkvist, Off-topic question:
In your example above using "let" is equivalent of using "var", true? There are no block-scopes there. Is using "let" still a better style?

@jeff-kilbride
Copy link

@vkelman
For me, "let" is a better style. Besides block-scoping, all "var" declarations are hoisted, whereas "let" are not. Declaring variables with "let" more closely mimics the way variables are declared in other languages -- which is why I prefer it. In ES6 environments, I find myself using "const" and "let" almost exclusively.

@cbrunnkvist
Copy link
Author

cbrunnkvist commented Jan 5, 2017

Wow, I didn't realize there was any response to this gist. :-)

@vkelman yes there is almost never any reason to pick var nowadays. Each function block is a block scope but const/let takes away any ambiguities about the intent. Btw, I always strive after a "least privilege" code style, so I should have written const not let in all cases since I never change any references. I guess I sloppy-copy-pasted this example together.

@cbrunnkvist
Copy link
Author

cbrunnkvist commented Jan 5, 2017

@vphantom that's what I wanted to demonstrate: the two main instances kick off in sequence (the two initial "starting" lines of output) but get their job done asynchronously, in parallell (the jumbled "step" output). ⏲️ ⏲️

Yeah, I could have completed it with Promise.all([main1, main2]).then(()=>{console.log('all done')}) but that would have ruined whatever simplicity 😸 remains in the example IMO.

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