async/timing.js

  1. /**
  2. * Asynchronous tools.
  3. *
  4. * @module async
  5. * @license Apache-2.0
  6. * @copyright Mat. 2018-present
  7. */
  8. import { identity } from "../func/tools";
  9. import { timeUnit } from "../utils/misc";
  10. /**
  11. * Delay current async execution by `time` miliseconds.
  12. *
  13. * Example:
  14. *
  15. * ```
  16. * (async () => {
  17. * await async.delay()
  18. * console.log("Hello ...")
  19. * await async.delay()
  20. * console.log("... world")
  21. * })()
  22. * ```
  23. *
  24. * @async
  25. * @function delay
  26. * @see [timeout]{@link module:async~timeout}
  27. * @param {Number} [time=timeUnit.second]
  28. * @param {Function} [passCancel] cancel => any
  29. * @returns {Promise.<Number>}
  30. */
  31. export const delay = (
  32. time = timeUnit.second,
  33. passCancel = identity,
  34. ) =>
  35. timeout(() => time, time, passCancel);
  36. /**
  37. * `setInterval` in `Promise` / `async` skin.
  38. *
  39. * Example 1:
  40. *
  41. * ```
  42. * global.x = 0
  43. * async.interval(
  44. * c => {
  45. * if (global.x === 10) { c("tada") }
  46. * else { global.x += 1 }
  47. * console.log("ping", Date.now())
  48. * }
  49. * )
  50. * .then(utils.to_("success"))
  51. * .catch(utils.to_("failure"))
  52. * ```
  53. *
  54. * Example 2:
  55. * ```
  56. * interval(
  57. * () => { console.log("Hey!"); return 42 },
  58. * c => timeout(() => c(), 4 * timeUnit.second)
  59. * )
  60. * .then(x => console.log("Finished:", x))
  61. * .catch(c => console.log("Error:", c))
  62. * ```
  63. *
  64. * @async
  65. * @function interval
  66. * @param {Function} f
  67. * @param {Function} [passClear] (Function) => any
  68. * @param {Number} [time=timeUnit.second]
  69. * @returns {Promise.<any>}
  70. */
  71. export const interval = (
  72. f,
  73. passClear = identity,
  74. time = timeUnit.second,
  75. ) => {
  76. let resolve = null, handle = null, result = null;
  77. const
  78. clear = (...args) => {
  79. clearInterval(handle);
  80. resolve(...(args.length > 0 ? args : [result]));
  81. return result;
  82. },
  83. promise = new Promise((res, rej) => {
  84. resolve = res;
  85. handle = setInterval(() => {
  86. try { result = f(clear); }
  87. catch (ex) {
  88. clearInterval(handle);
  89. rej(ex);
  90. }
  91. }, time);
  92. });
  93. passClear(clear);
  94. return promise;
  95. };
  96. /**
  97. * `setTimeout` in `Promise` / `async` skin.
  98. *
  99. * Example:
  100. *
  101. * ```
  102. * async.timeout(
  103. * () => { console.log("Hey!"); return 42 }, 2000,
  104. * c => async.timeout(() => c("Cancelled!"), 1000)
  105. * )
  106. * .then(x => console.log("Success:", x))
  107. * .catch(c => console.log("Error or cancel:", c))
  108. * ```
  109. *
  110. * @async
  111. * @function timeout
  112. * @param {Function} f
  113. * @param {Number} [time=timeUnit.second]
  114. * @param {Function} [passCancel] cancel => any
  115. * @returns {Promise.<any>}
  116. */
  117. export const timeout = (
  118. f,
  119. time = timeUnit.second,
  120. passCancel = identity,
  121. ) => {
  122. let reject = null, handle = null;
  123. const promise = new Promise((res, rej) => {
  124. reject = rej;
  125. handle = setTimeout(() => {
  126. try { res(f()); }
  127. catch (ex) { rej(ex); }
  128. }, time);
  129. });
  130. passCancel(reason => {
  131. clearTimeout(handle);
  132. reject(reason);
  133. });
  134. return promise;
  135. };