Skip to content

Instantly share code, notes, and snippets.

@XoseLluis
Last active August 29, 2015 14:23
Show Gist options
  • Save XoseLluis/df9a54ecc12f33584b3e to your computer and use it in GitHub Desktop.
Save XoseLluis/df9a54ecc12f33584b3e to your computer and use it in GitHub Desktop.
Simulate C# async/await in ES6 thanks to generators
// http://deploytonenyures.blogspot.fr/2015/06/simulating-await-with-es6-generators.html
//as of node 0.12.4 we still need the -harmony flag to enable generators
var print = console.log;
//---------------------
// class used to represent an asynchronous operation
//it's a sort of "poor man's" Promise
//first parameter is an async function func, the remaining parameters are the normal params
//then a callback will be provided later on by setting the nextStep property
//func will call nextStep once finished passing over its result
function TaskInfo(){
this.arguments = [].slice.call(arguments, 0);
this.func = this.arguments.shift();
this.nextStep = null;
}
TaskInfo.prototype.run = function(){
//duplicate it
var args = this.arguments.slice();
args.push(this.nextStep);
this.func.apply(this, args);
};
//---------------------
//receives a generator function that returns a TaskInfo on each "iteration"
//this function implements the asynchronous loop that will keep calling the generator object
function awaitEnableAndRun(generatorFunc, endCallback){
var loop = function(returnValue){
//notice that the first call to next is supposed to crash if it receives a parameter,
//but it's not the case as of this writing neither in node or firefox. If it were so, I would have to adapt this a bit
var res = generator.next(returnValue);
if (!res.done){
var taskInfo = res.value;
taskInfo.nextStep = loop;
taskInfo.run();
}
else{
endCallback();
}
};
var generator = generatorFunc();
loop();
}
//---------------------
//sample of asynchronous function
function getFileAsync(fileId, onFinishedCallback){
print("file retrieval " + fileId + " started");
setTimeout(function(){
print("file retrieval finished");
//result of the async operation
var file = {
id : fileId,
content: null
};
onFinishedCallback(file);
}, 4000);
}
//using yield and TaskInfo to simulate c#'s await
function* getFiles(/*onFinished*/){
print("getFiles started");
//equivalent to a C# await call:
//return a function
var file = yield (new TaskInfo(getFileAsync, "111"));
print("operating with file1: " + file.id);
//equivalent to a C# await call:
file = yield (new TaskInfo(getFileAsync, "222"));
print("operating with file2" + file.id);
//onFinished();
};
//let's go
print ("application started")
awaitEnableAndRun(getFiles, function(){
print("application finished");
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment