From 089509d380e0be952d2de0437a45dfd9bf664ffb Mon Sep 17 00:00:00 2001 From: Chris Eineke Date: Wed, 7 Jan 2015 02:15:04 -0500 Subject: [PATCH] Introduce join guard. --- guard.js | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/guard.js b/guard.js index 38924cae..5b9abe3f 100644 --- a/guard.js +++ b/guard.js @@ -15,6 +15,7 @@ define(function(require) { var slice = Array.prototype.slice; guard.n = n; + guard.join = join; return guard; @@ -31,7 +32,9 @@ define(function(require) { var args = slice.call(arguments); return when(condition()).withThis(this).then(function(exit) { - return when(f.apply(this, args))['finally'](exit); + return when(f.apply(this, args)).tap(exit); + }, function (exit) { + return exit; }); }; } @@ -68,5 +71,38 @@ define(function(require) { } } + /** + * Creates a condition that allows only one concurrent execution of a guarded function + */ + function join() { + var first = false; + var value; + var waiting = []; + + return function enter() { + return when.promise(function(resolve, reject) { + if (!first) { + resolve(exit); + first = true; + } else { + waiting.push([ resolve, reject ]); + } + }); + }; + + function exit(result) { + waiting.forEach(function (waiting) { + waiting[1](result); + }); + reset(); + } + + function reset() { + first = false; + value = undefined; + waiting = []; + } + } + }); }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));