55 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			55 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 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 | ||
|  | } |