Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/tryEach.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import eachSeries from './eachSeries.js'
import wrapAsync from './internal/wrapAsync.js'
import awaitify from './internal/awaitify.js'
import breakLoop from './internal/breakLoop.js'

/**
* It runs each task in series but stops whenever any of the functions were
* successful. If one of the tasks were successful, the `callback` will be
* passed the result of the successful task. If all tasks fail, the callback
* will be passed the error and result (if any) of the final attempt.
* If iterating over an async collection fails, the callback receives that error.
*
* @name tryEach
* @static
Expand Down Expand Up @@ -53,9 +55,9 @@ function tryEach(tasks, callback) {
result = args;
}
error = err;
taskCb(err ? null : {});
taskCb(null, err ? undefined : breakLoop);
});
}, () => callback(error, result));
}, err => callback(err || error, result));
}

export default awaitify(tryEach)
35 changes: 35 additions & 0 deletions test/es2017/asyncGenerators.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,41 @@ module.exports = function () {

this.retries(3);

it('should reject tryEach when the async generator fails before yielding a task', async () => {
const error = new Error('iterator failed')
async function * tasks () {
yield await Promise.reject(error)
}

await async.tryEach(tasks()).then(
() => { throw new Error('expected tryEach to reject') },
err => { expect(err).to.equal(error) }
)
})

it('should report tryEach iterator errors after a failed task', async () => {
const error = new Error('iterator failed')
async function * tasks () {
yield cb => cb(new Error('task failed'), 'last result')
throw error
}

const outcome = await new Promise(resolve => {
async.tryEach(tasks(), (err, result) => resolve({err, result}))
})
expect(outcome.err).to.equal(error)
expect(outcome.result).to.equal('last result')
})

it('should stop tryEach reading an async generator after a successful task', async () => {
async function * tasks () {
yield cb => cb(null, 'result')
throw new Error('should not request another task')
}

expect(await async.tryEach(tasks())).to.equal('result')
})

it('should handle async generators in each', (done) => {
const calls = []
async.each(range(5),
Expand Down
Loading