-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1365 from alFReD-NSH/try
Add async.tryEach
- Loading branch information
Showing
3 changed files
with
147 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import noop from 'lodash/noop'; | ||
import eachSeries from './eachSeries'; | ||
import rest from './internal/rest'; | ||
|
||
/** | ||
* 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. | ||
* | ||
* @name tryEach | ||
* @static | ||
* @memberOf module:ControlFlow | ||
* @method | ||
* @category Control Flow | ||
* @param {Array|Iterable|Object} tasks - A collection containing functions to | ||
* run, each function is passed a `callback(err, result)` it must call on | ||
* completion with an error `err` (which can be `null`) and an optional `result` | ||
* value. | ||
* @param {Function} [callback] - An optional callback which is called when one | ||
* of the tasks has succeeded, or all have failed. It receives the `err` and | ||
* `result` arguments of the last attempt at completing the `task`. Invoked with | ||
* (err, results). | ||
* @example | ||
* async.try([ | ||
* function getDataFromFirstWebsite(callback) { | ||
* // Try getting the data from the first website | ||
* callback(err, data); | ||
* }, | ||
* function getDataFromSecondWebsite(callback) { | ||
* // First website failed, | ||
* // Try getting the data from the backup website | ||
* callback(err, data); | ||
* } | ||
* ], | ||
* // optional callback | ||
* function(err, results) { | ||
* Now do something with the data. | ||
* }); | ||
* | ||
*/ | ||
export default function tryEach(tasks, callback) { | ||
var error = null; | ||
var result; | ||
callback = callback || noop; | ||
eachSeries(tasks, function(task, callback) { | ||
task(rest(function (err, args) { | ||
if (args.length <= 1) { | ||
args = args[0]; | ||
} | ||
error = err; | ||
result = args; | ||
callback(!err); | ||
})); | ||
}, function () { | ||
callback(error, result); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
var async = require('../lib'); | ||
var expect = require('chai').expect; | ||
var assert = require('assert'); | ||
|
||
describe('try', function () { | ||
it('no callback', function () { | ||
async.tryEach([]); | ||
}); | ||
it('empty', function (done) { | ||
async.tryEach([], function (err, results) { | ||
expect(err).to.equal(null); | ||
expect(results).to.eql(undefined); | ||
done(); | ||
}); | ||
}); | ||
it('one task, multiple results', function (done) { | ||
var RESULTS = ['something', 'something2']; | ||
async.tryEach([ | ||
function (callback) { | ||
callback(null, RESULTS[0], RESULTS[1]); | ||
} | ||
], function (err, results) { | ||
expect(err).to.equal(null); | ||
expect(results).to.eql(RESULTS); | ||
done(); | ||
}); | ||
}); | ||
it('one task', function (done) { | ||
var RESULT = 'something'; | ||
async.tryEach([ | ||
function (callback) { | ||
callback(null, RESULT); | ||
} | ||
], function (err, results) { | ||
expect(err).to.equal(null); | ||
expect(results).to.eql(RESULT); | ||
done(); | ||
}); | ||
}); | ||
it('two tasks, one failing', function (done) { | ||
var RESULT = 'something'; | ||
async.tryEach([ | ||
function (callback) { | ||
callback(new Error('Failure'), {}); | ||
}, | ||
function (callback) { | ||
callback(null, RESULT); | ||
} | ||
], function (err, results) { | ||
expect(err).to.equal(null); | ||
expect(results).to.eql(RESULT); | ||
done(); | ||
}); | ||
}); | ||
it('two tasks, both failing', function (done) { | ||
var ERROR_RESULT = new Error('Failure2'); | ||
async.tryEach([ | ||
function (callback) { | ||
callback(new Error('Should not stop here')); | ||
}, | ||
function (callback) { | ||
callback(ERROR_RESULT); | ||
} | ||
], function (err, results) { | ||
expect(err).to.equal(ERROR_RESULT); | ||
expect(results).to.eql(undefined); | ||
done(); | ||
}); | ||
}); | ||
it('two tasks, non failing', function (done) { | ||
var RESULT = 'something'; | ||
async.tryEach([ | ||
function (callback) { | ||
callback(null, RESULT); | ||
}, | ||
function () { | ||
assert.fail('Should not been called'); | ||
}, | ||
], function (err, results) { | ||
expect(err).to.equal(null); | ||
expect(results).to.eql(RESULT); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
|