diff --git a/lib/internal/asyncEachOfLimit.js b/lib/internal/asyncEachOfLimit.js index 46b08c6e0..b06c2565f 100644 --- a/lib/internal/asyncEachOfLimit.js +++ b/lib/internal/asyncEachOfLimit.js @@ -1,4 +1,5 @@ import breakLoop from './breakLoop.js' +import onlyOnce from './onlyOnce.js' // for async generators export default function asyncEachOfLimit(generator, limit, iteratee, callback) { @@ -26,7 +27,7 @@ export default function asyncEachOfLimit(generator, limit, iteratee, callback) { return; } running++ - iteratee(value, idx, iterateeCallback) + iteratee(value, idx, onlyOnce(iterateeCallback)) idx++ replenish() }).catch(handleError) diff --git a/test/es2017/asyncGenerators.js b/test/es2017/asyncGenerators.js index e4c00549f..b40a627ea 100644 --- a/test/es2017/asyncGenerators.js +++ b/test/es2017/asyncGenerators.js @@ -28,6 +28,21 @@ module.exports = function () { this.retries(3); + it('should reject repeated iteratee callbacks for async generators', async () => { + async function * values () { + yield 1 + yield 2 + } + + await async.eachOfLimit(values(), 1, (value, key, callback) => { + callback(null) + callback(null) + }).then( + () => { throw new Error('expected repeated callback to reject') }, + err => { expect(err.message).to.equal('Callback was already called.') } + ) + }) + it('should reject tryEach when the async generator fails before yielding a task', async () => { const error = new Error('iterator failed') async function * tasks () {