reflect.js

  1. import initialParams from './internal/initialParams';
  2. import slice from './internal/slice';
  3. import wrapAsync from './internal/wrapAsync';
  4. /**
  5. * Wraps the async function in another function that always completes with a
  6. * result object, even when it errors.
  7. *
  8. * The result object has either the property `error` or `value`.
  9. *
  10. * @name reflect
  11. * @static
  12. * @memberOf module:Utils
  13. * @method
  14. * @category Util
  15. * @param {AsyncFunction} fn - The async function you want to wrap
  16. * @returns {Function} - A function that always passes null to it's callback as
  17. * the error. The second argument to the callback will be an `object` with
  18. * either an `error` or a `value` property.
  19. * @example
  20. *
  21. * async.parallel([
  22. * async.reflect(function(callback) {
  23. * // do some stuff ...
  24. * callback(null, 'one');
  25. * }),
  26. * async.reflect(function(callback) {
  27. * // do some more stuff but error ...
  28. * callback('bad stuff happened');
  29. * }),
  30. * async.reflect(function(callback) {
  31. * // do some more stuff ...
  32. * callback(null, 'two');
  33. * })
  34. * ],
  35. * // optional callback
  36. * function(err, results) {
  37. * // values
  38. * // results[0].value = 'one'
  39. * // results[1].error = 'bad stuff happened'
  40. * // results[2].value = 'two'
  41. * });
  42. */
  43. export default function reflect(fn) {
  44. var _fn = wrapAsync(fn);
  45. return initialParams(function reflectOn(args, reflectCallback) {
  46. args.push(function callback(error, cbArg) {
  47. if (error) {
  48. reflectCallback(null, { error: error });
  49. } else {
  50. var value;
  51. if (arguments.length <= 2) {
  52. value = cbArg
  53. } else {
  54. value = slice(arguments, 1);
  55. }
  56. reflectCallback(null, { value: value });
  57. }
  58. });
  59. return _fn.apply(this, args);
  60. });
  61. }