summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolan McMahon <caolan@caolanmcmahon.com>2013-01-31 04:42:35 -0800
committerCaolan McMahon <caolan@caolanmcmahon.com>2013-01-31 04:42:35 -0800
commit9a2594e52ecd3bce2bcb7c4adc2ee2bb2226e78d (patch)
treed25e71d4405e48ee2e9bc7c4f4e226e3df47e098
parentd39b8f995d41b23f52acbe3d0ea8aeae31c87287 (diff)
parentbb43829d29e91c8f314704876293ae3f7b22c82d (diff)
downloadasync-9a2594e52ecd3bce2bcb7c4adc2ee2bb2226e78d.tar.gz
Merge pull request #200 from coreyjewett/master
Throw Error when callback is called too many times.
-rw-r--r--lib/async.js17
-rw-r--r--test/test-async.js28
2 files changed, 39 insertions, 6 deletions
diff --git a/lib/async.js b/lib/async.js
index 99a4866..0480a30 100644
--- a/lib/async.js
+++ b/lib/async.js
@@ -12,6 +12,15 @@
return async;
};
+ function only_once(fn) {
+ var called = false;
+ return function() {
+ if (called) throw new Error("Callback was already called.");
+ called = true;
+ fn.apply(root, arguments);
+ }
+ }
+
//// cross-browser compatiblity functions ////
var _forEach = function (arr, iterator) {
@@ -76,7 +85,7 @@
}
var completed = 0;
_forEach(arr, function (x) {
- iterator(x, function (err) {
+ iterator(x, only_once(function (err) {
if (err) {
callback(err);
callback = function () {};
@@ -87,7 +96,7 @@
callback(null);
}
}
- });
+ }));
});
};
@@ -654,14 +663,14 @@
var task = q.tasks.shift();
if(q.empty && q.tasks.length == 0) q.empty();
workers += 1;
- worker(task.data, function () {
+ worker(task.data, only_once(function() {
workers -= 1;
if (task.callback) {
task.callback.apply(task, arguments);
}
if(q.drain && q.tasks.length + workers == 0) q.drain();
q.process();
- });
+ }));
}
},
length: function () {
diff --git a/test/test-async.js b/test/test-async.js
index d46b340..fa97042 100644
--- a/test/test-async.js
+++ b/test/test-async.js
@@ -609,6 +609,18 @@ exports['forEach'] = function(test){
});
};
+exports['forEach extra callback'] = function(test){
+ var count = 0;
+ async.forEach([1,3,2], function(val, callback) {
+ count++;
+ callback();
+ test.throws(callback);
+ if (count == 3) {
+ test.done();
+ }
+ });
+};
+
exports['forEach empty array'] = function(test){
test.expect(1);
async.forEach([], function(x, callback){
@@ -1486,7 +1498,7 @@ exports['queue'] = function (test) {
test.equal(q.length(), 4);
test.equal(q.concurrency, 2);
- setTimeout(function () {
+ q.drain = function () {
test.same(call_order, [
'process 2', 'callback 2',
'process 1', 'callback 1',
@@ -1496,7 +1508,7 @@ exports['queue'] = function (test) {
test.equal(q.concurrency, 2);
test.equal(q.length(), 0);
test.done();
- }, 800);
+ };
};
exports['queue changing concurrency'] = function (test) {
@@ -1585,6 +1597,18 @@ exports['queue push without callback'] = function (test) {
}, 800);
};
+exports['queue too many callbacks'] = function (test) {
+ var q = async.queue(function (task, callback) {
+ callback();
+ test.throws(function() {
+ callback();
+ });
+ test.done();
+ }, 2);
+
+ q.push(1);
+};
+
exports['queue bulk task'] = function (test) {
var call_order = [],
delays = [160,80,240,80];