summaryrefslogtreecommitdiff
path: root/lib/auto.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/auto.js')
-rw-r--r--lib/auto.js57
1 files changed, 39 insertions, 18 deletions
diff --git a/lib/auto.js b/lib/auto.js
index 327383b..0e9d108 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) {
@@ -69,6 +72,7 @@ export default function (tasks, concurrency, callback) {
});
safeResults[k] = args;
hasError = true;
+ listeners = [];
callback(err, safeResults);
}
@@ -77,37 +81,54 @@ 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) &&
+ return runningTasks < concurrency &&
+ !baseHas(results, k) &&
+ !hasError &&
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();
}
}
});