diff --git a/lib/helpers/cursor/eachAsync.js b/lib/helpers/cursor/eachAsync.js index 5ab0f5785fc..5e6207c7687 100644 --- a/lib/helpers/cursor/eachAsync.js +++ b/lib/helpers/cursor/eachAsync.js @@ -38,10 +38,11 @@ module.exports = function eachAsync(next, fn, options, callback) { const iterate = function(callback) { let drained = false; const nextQueue = async.queue(function(task, cb) { - if (drained) return cb(); + if (drained) { + return cb(); + } next(function(err, doc) { if (err) return cb(err); - if (!doc) drained = true; cb(null, doc); }); }, 1); @@ -49,7 +50,13 @@ module.exports = function eachAsync(next, fn, options, callback) { const getAndRun = function(cb) { nextQueue.push({}, function(err, doc) { if (err) return cb(err); - if (!doc) return cb(); + if (drained) { + return; + } + if (doc == null) { + drained = true; + return callback(null); + } handleNextResult(doc, function(err) { if (err) return cb(err); // Make sure to clear the stack re: gh-4697 @@ -60,9 +67,18 @@ module.exports = function eachAsync(next, fn, options, callback) { }); }; - async.times(parallel, function(n, cb) { - getAndRun(cb); - }, callback); + let error = null; + for (let i = 0; i < parallel; ++i) { + getAndRun(err => { + if (error != null) { + return; + } + if (err != null) { + error = err; + return callback(err); + } + }); + } }; return utils.promiseOrCallback(callback, cb => { diff --git a/test/aggregate.test.js b/test/aggregate.test.js index 5854659b4c4..c20d7cd374c 100644 --- a/test/aggregate.test.js +++ b/test/aggregate.test.js @@ -1288,10 +1288,10 @@ describe('aggregate: ', function() { return MyModel.aggregate([{ $sort: { name: 1 } }]). cursor(). exec(). - eachAsync(checkDoc, { parallel: 2}).then(function() { + eachAsync(checkDoc, { parallel: 2 }).then(function() { assert.ok(Date.now() - startedAt[1] >= 100); assert.equal(startedAt.length, 2); - assert.ok(startedAt[1] - startedAt[0] < 50); + assert.ok(startedAt[1] - startedAt[0] < 50, `${startedAt[1] - startedAt[0]}`); assert.deepEqual(names.sort(), expectedNames); done(); });