during.js

  1. import noop from 'lodash/noop';
  2. import onlyOnce from './internal/onlyOnce';
  3. import wrapAsync from './internal/wrapAsync';
  4. /**
  5. * Like [`whilst`]{@link module:ControlFlow.whilst}, except the `test` is an asynchronous function that
  6. * is passed a callback in the form of `function (err, truth)`. If error is
  7. * passed to `test` or `fn`, the main callback is immediately called with the
  8. * value of the error.
  9. *
  10. * @name during
  11. * @static
  12. * @memberOf module:ControlFlow
  13. * @method
  14. * @see [async.whilst]{@link module:ControlFlow.whilst}
  15. * @category Control Flow
  16. * @param {AsyncFunction} test - asynchronous truth test to perform before each
  17. * execution of `fn`. Invoked with (callback).
  18. * @param {AsyncFunction} fn - An async function which is called each time
  19. * `test` passes. Invoked with (callback).
  20. * @param {Function} [callback] - A callback which is called after the test
  21. * function has failed and repeated execution of `fn` has stopped. `callback`
  22. * will be passed an error, if one occurred, otherwise `null`.
  23. * @example
  24. *
  25. * var count = 0;
  26. *
  27. * async.during(
  28. * function (callback) {
  29. * return callback(null, count < 5);
  30. * },
  31. * function (callback) {
  32. * count++;
  33. * setTimeout(callback, 1000);
  34. * },
  35. * function (err) {
  36. * // 5 seconds have passed
  37. * }
  38. * );
  39. */
  40. export default function during(test, fn, callback) {
  41. callback = onlyOnce(callback || noop);
  42. var _fn = wrapAsync(fn);
  43. var _test = wrapAsync(test);
  44. function next(err) {
  45. if (err) return callback(err);
  46. _test(check);
  47. }
  48. function check(err, truth) {
  49. if (err) return callback(err);
  50. if (!truth) return callback(null);
  51. _fn(next);
  52. }
  53. _test(check);
  54. }