Last active
August 29, 2015 14:22
-
-
Save benjamn/b23dcb4cc6472be12291 to your computer and use it in GitHub Desktop.
AwaitArgument example
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
let runtime = { | |
awrap(argument) { | |
return new AwaitArgument(argument); | |
}, | |
"async"(generatorFunction) { | |
let generator = generatorFunction(); | |
let previousPromise; | |
function callNext(...args) { | |
let result = generator.next(...args); | |
if (result.value instanceof AwaitArgument) { | |
// If the generator yields an AwaitArgument, return a Promise for | |
// the eventual result of the next yield (or return). | |
return Promise.resolve(result.value.argument).then( | |
result => generator.next(result), | |
error => generator.throw(error) | |
); | |
} | |
// If the generator produced an iteration result with an unwrapped | |
// .value, simply return that iteration result. | |
return result; | |
} | |
return { // Simplified AsyncIterator object (no .throw or .return). | |
next(...args) { | |
let currentPromise = previousPromise | |
? previousPromise.then(() => callNext(...args)) | |
: new Promise(resolve => resolve(callNext(...args))); | |
previousPromise = currentPromise.catch(() => "suppressed"); | |
return currentPromise; | |
} | |
}; | |
} | |
}; | |
// This wrapper type can remain an implementation detail, visible only to | |
// methods of the runtime. | |
class AwaitArgument { | |
constructor(arg) { | |
this.argument = arg; | |
} | |
} | |
export default runtime; |
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
import runtime from "./asyncRuntime.es6.js"; | |
function getLinesAsync(fileName) { | |
return runtime.async(function*() { | |
let asyncFile = openFileAsync(fileName); | |
let lineCount = 0; | |
while (true) { | |
// In an async generator function, expressions of the form `await x` | |
// become `yield runtime.awrap(x)`, thus yielding an AwaitArgument. | |
let line = yield runtime.awrap(asyncFile.getLine()); | |
if (line === null) { | |
break; | |
} | |
++lineCount; | |
// Normal yield expressions don't need to be transformed. | |
let action = yield runtime.awrap(yield line); | |
if (action === "break") { | |
break; | |
} | |
} | |
return lineCount; | |
}); | |
} |
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
async function *getLinesAsync(fileName) { | |
let asyncFile = openFileAsync(fileName); | |
let lineCount = 0; | |
while (true) { | |
// Assume asyncFile.getLine() returns a Promise<String | null>. | |
let line = await asyncFile.getLine(); | |
if (line === null) { | |
break; | |
} | |
++lineCount; | |
// In case this line requires asynchronous processing, await the | |
// result of the yield expression. | |
let action = await yield line; | |
if (action === "break") { | |
break; | |
} | |
} | |
return lineCount; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment