Spaces:
Sleeping
Sleeping
var wrappy = require('wrappy') | |
var reqs = Object.create(null) | |
var once = require('once') | |
module.exports = wrappy(inflight) | |
function inflight (key, cb) { | |
if (reqs[key]) { | |
reqs[key].push(cb) | |
return null | |
} else { | |
reqs[key] = [cb] | |
return makeres(key) | |
} | |
} | |
function makeres (key) { | |
return once(function RES () { | |
var cbs = reqs[key] | |
var len = cbs.length | |
var args = slice(arguments) | |
// XXX It's somewhat ambiguous whether a new callback added in this | |
// pass should be queued for later execution if something in the | |
// list of callbacks throws, or if it should just be discarded. | |
// However, it's such an edge case that it hardly matters, and either | |
// choice is likely as surprising as the other. | |
// As it happens, we do go ahead and schedule it for later execution. | |
try { | |
for (var i = 0; i < len; i++) { | |
cbs[i].apply(null, args) | |
} | |
} finally { | |
if (cbs.length > len) { | |
// added more in the interim. | |
// de-zalgo, just in case, but don't call again. | |
cbs.splice(0, len) | |
process.nextTick(function () { | |
RES.apply(null, args) | |
}) | |
} else { | |
delete reqs[key] | |
} | |
} | |
}) | |
} | |
function slice (args) { | |
var length = args.length | |
var array = [] | |
for (var i = 0; i < length; i++) array[i] = args[i] | |
return array | |
} | |