Last active
August 29, 2015 14:23
-
-
Save XoseLluis/df9a54ecc12f33584b3e to your computer and use it in GitHub Desktop.
Simulate C# async/await in ES6 thanks to generators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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