Skip to content

Instantly share code, notes, and snippets.

@Raynos
Created October 6, 2012 23:18
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 Raynos/3846478 to your computer and use it in GitHub Desktop.
Save Raynos/3846478 to your computer and use it in GitHub Desktop.

Async composition with domains

An async function composition allows you to combine multiple asynchronous functions into a single function.

Any errors from any of the functions will go to the domain.

Example

var compose = require("compose-async-domain")
    , assert = require("assert")
    , Domain = require("domain").create

var domainOne = Domain()
    , one = compose(domainOne
        , function third(arg, callback) {
            callback(null, arg * 2)
        }
        , function second(arg, callback) {
            callback(null, arg + 2)
        }
        , function first(arg, callback) {
            callback(null, arg * 2)
        })

domainOne.on("error", function (err) {
    // there are no errors
    assert.ok(false, "should never fire")
})

one(2, function (result) {
    assert.equal(result, 12)
})

var domainTwo = Domain()
    , two = compose(domainTwo
        , function third(data, callback) {
            if (data === "") {
                return callback(new Error("empty :("))
            }

            callback(null, data)
        }
        , function second(data, callback) {
            callback(null, data.toString().toUpperCase())
        }
        , function first(filePath, callback) {
            fs.readFile(filePath, callback)
        })

domainTwo.on("error", function (err) {
    // error from empty file
    assert.equal(err.message, "empty :(")
})

two("sensibleFile.txt", function (data) {
    // upper cased data
})

two("emptyFile.txt", function () {
    // never gets called
})
var composeAsync = require("composite").async
, toArray = require("to-array")
module.exports = composeAsyncDomain
function composeAsyncWithThrown(domain) {
var args = toArray(arguments, 1)
.map(wrap.bind(null, domain))
, result = composeAsync.apply(null, args)
return wrap(domain, result)
}
function wrap(domain, f) {
return wrapped
function wrapped() {
var self = this
, args = toArray(arguments)
, cb = args[args.length - 1]
if (typeof cb === "function") {
args[args.length - 1] = domain.intercept(cb)
}
domain.run(function () {
f.apply(self, args)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment