-
-
Save mraleph/1364383 to your computer and use it in GitHub Desktop.
Shallow coroutines based on Harmony 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
// Variant of Tim Caswell's "fibers" proposal based on Harmony generators. | |
// Make generator into a shallow coroutine. | |
function GF(g) { | |
var f = g(resume); | |
function resume (value) { f.send(value); } | |
f.next(); | |
} | |
function readfile(filename, next) { | |
GF(function* (resume) { | |
var err, fd, stat, chunks; | |
console.log("opening..."); | |
// This is a normal async function. It doesn't know anything about coroutines. | |
// The FS.open call is non-blocking, even for this coroutine | |
// Destructuring assignment, wait returns the arguments that resume got. | |
// The call to wait will suspend this coroutine and only resume when the | |
// `resume` callback eventually gets called. | |
[err, fd] = yield FS.open(filename, "r", "0644", resume); | |
if (err) { next(err); return; } | |
// Same thing, but doing a fstat on the fd | |
console.log("fstatting..."); | |
[err, stat] = yield FS.fstat(fd, resume); | |
if (err) { next(err); return; } | |
// Here is an example using a blocking loop to read a file in chunks | |
console.log("reading..."); | |
var chunk, length, offset = 0; | |
do { | |
[err, chunk, length] = yield FS.read(fd, offset, 72, resume); | |
if (err) { next(err); return; } | |
chunks.push(chunk); | |
offset = offset + length; | |
} while (length); | |
console.log("pausing..."); | |
// Works for other async functions too, not just node ones. | |
// Sleep this coroutine for 500ms | |
yield setTimeout(resume, 500); | |
console.log("closing..."); | |
[err] = yield FS.close(fd, resume); | |
if (err) { next(err); return; } | |
next(null, chunks, stat); | |
}); | |
} |
@creationix done.
Harmony generators add generator.throw(error)
, like send, but effecting an exception at the yield
. The proposal also adds support for return values from generators; if a generator halts at an explicit return, a ReturnValue
exception inherited from StopIteration
is thrown with the exception.value
of the return.
This is a function similar to Vyacheslav’s GF
: https://github.com/kriskowal/q/blob/8ff517e193185b100feb881185957a7f211b4c72/q.js#L546-602
It is a simple decorator that turns a generator into a promise-returning function and yields on promises. If the promises are rejected, they get propagated as exceptions. The return value of the generator resolves the returned promise.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice, update the comments and gist description and it will make more sense to others.