|  | 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 | 
|  | } |