Skip to content

Instantly share code, notes, and snippets.

@creationix
Last active December 18, 2015 10:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creationix/5766132 to your computer and use it in GitHub Desktop.
Save creationix/5766132 to your computer and use it in GitHub Desktop.
continuable vs callback for stream generating functions
// This function returns a stream, but optionally can return a continuable for a stream
// so that the caller can check for early errors before hooking stuff up.
function readFile(path, options) {
// Options is optional, so set a default.
options = options || {};
if (options.check) {
return function (callback) {
fs.open(path, "r", function (err, fd) {
if (err) return callback(err);
callback(null, makeStream(fd, options));
});
}
}
return makeStream(path, options);
}
// This is the callback version of the continuable-based function above
function readFile(path, options, callback) {
// Handle the optional argument in the middle before the callback
if (typeof options === "function" && typeof callback === "undefined") {
callback = options;
options = {};
}
else if (!options) {
options = {};
}
if (callback) {
fs.open(path, "r", function (err, fd) {
if (err) return callback(err);
callback(null, makeStream(fd, options));
});
return;
}
return makeStream(path, options);
}
// Using either mode without the callback/continuable is easy
var stream = readFile("/my/path.txt");
// now connect the stream to stuff.
// but early errors like ENOENT will appear as stream errors.
// But suppose I want to check the error code using the callback
readFile("/my/path.txt", function (err, stream) {
if (err) throw new Error("Don't pipe me up, I'm bad");
// now connect the stream to stuff.
});
// Or the same thing using continuable style
var continuable = readFile("/my/Path.txt", {check: true})
continuable(function (err, stream) {
if (err) throw new Error("Don't pipe me up, I'm bad");
// now connect the stream to stuff.
});
// For use with yield, suppose that instead of forwarding all errors to the callback, we treated ENOENT specially.
// ...
// if (err) {
// if (err.code === "ENOENT") return callback();
// return callback(err);
// }
// callback(null, makeStream(fd, options);
// ...
// continuable style
run(function* () {
var stream = yield readFile("/my/path.txt", {check: true})
if (stream) {
// pipe to other stuff
}
});
// resume style
run(function* (resume) {
var stream = yield readFile("/my/path.txt", resume());
if (stream) {
// pipe to other stuff
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment