diff options
Diffstat (limited to 'lib/auto.js')
-rw-r--r-- | lib/auto.js | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/lib/auto.js b/lib/auto.js index 327383b..21fbb08 100644 --- a/lib/auto.js +++ b/lib/auto.js @@ -34,13 +34,16 @@ export default function (tasks, concurrency, callback) { var hasError = false; var listeners = []; + function addListener(fn) { listeners.unshift(fn); } + function removeListener(fn) { var idx = indexOf(listeners, fn); if (idx >= 0) listeners.splice(idx, 1); } + function taskComplete() { remainingTasks--; arrayEach(listeners.slice(), function (fn) { @@ -77,37 +80,52 @@ export default function (tasks, concurrency, callback) { setImmediate(taskComplete); } }); + var requires = task.slice(0, task.length - 1); - // prevent dead-locks - var len = requires.length; - var dep; - while (len--) { - if (!(dep = tasks[requires[len]])) { - throw new Error('Has non-existent dependency in ' + - requires.join(', ')); - } - if (isArray(dep) && indexOf(dep, k) >= 0) { - throw new Error('Has cyclic dependencies'); + + checkForDeadlocks(); + + if (ready()) { + startNext(); + } else { + addListener(listener); + } + + function checkForDeadlocks() { + var len = requires.length; + var dep; + while (len--) { + if (!(dep = tasks[requires[len]])) { + throw new Error('Has non-existent dependency in ' + + requires.join(', ')); + } + if (isArray(dep) && indexOf(dep, k) >= 0) { + throw new Error('Has cyclic dependencies'); + } } } + function ready() { return runningTasks < concurrency && !baseHas(results, k) && arrayEvery(requires, function (x) { return baseHas(results, x); }); } - if (ready()) { + + function startNext() { runningTasks++; - task[task.length - 1](taskCallback, results); - } - else { - addListener(listener); + var taskFn = task[task.length - 1]; + if (requires.length > 0) { + taskFn(results, taskCallback); + } else { + taskFn(taskCallback); + } } + function listener() { if (ready()) { - runningTasks++; removeListener(listener); - task[task.length - 1](taskCallback, results); + startNext(); } } }); |