index.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*@flow*/
  2. /*
  3. * Caleb James DeLisle
  4. * Sat Mar 23 01:42:29 EDT 2013
  5. * Public Domain or MIT License
  6. */
  7. /*::
  8. type WaitFor_t = (?(...any)=>void)=>((...any)=>void);
  9. type NthenRet_t = { nThen: Nthen_t, orTimeout:((WaitFor_t)=>void, number)=>NthenRet_t };
  10. type Nthen_t = ((WaitFor_t)=>void)=>NthenRet_t;
  11. module.exports = */ (function() {
  12. var nThen /*:Nthen_t*/ = function(next) {
  13. var funcs /*:Array<(WaitFor_t)=>void>*/ = [];
  14. var timeouts = [];
  15. var calls = 0;
  16. var abort;
  17. var waitFor = function(func) {
  18. calls++;
  19. return function() {
  20. if (func) {
  21. func.apply(null, arguments);
  22. }
  23. calls = (calls || 1) - 1;
  24. while (!calls && funcs.length && !abort) {
  25. funcs.shift()(waitFor);
  26. }
  27. };
  28. };
  29. waitFor.abort = function () {
  30. timeouts.forEach(clearTimeout);
  31. abort = 1;
  32. };
  33. var ret = {
  34. nThen: function(next) {
  35. if (!abort) {
  36. if (!calls) {
  37. next(waitFor);
  38. } else {
  39. funcs.push(next);
  40. }
  41. }
  42. return ret;
  43. },
  44. orTimeout: function(func, milliseconds) {
  45. if (abort) { return ret; }
  46. if (!milliseconds) { throw Error("Must specify milliseconds to orTimeout()"); }
  47. var cto;
  48. var timeout = setTimeout(function() {
  49. while (funcs.shift() !== cto) { }
  50. func(waitFor);
  51. calls = (calls || 1) - 1;
  52. while (!calls && funcs.length) { funcs.shift()(waitFor); }
  53. }, milliseconds);
  54. funcs.push(cto = function() {
  55. var idx = timeouts.indexOf(timeout);
  56. if (idx > -1) {
  57. timeouts.splice(idx, 1);
  58. clearTimeout(timeout);
  59. return;
  60. }
  61. throw new Error('timeout not listed in array');
  62. });
  63. timeouts.push(timeout);
  64. return ret;
  65. }
  66. };
  67. return ret.nThen(next);
  68. };
  69. if (typeof(module) !== 'undefined') { module.exports = nThen; }
  70. else if (typeof(window.define) === 'function' && window.define.amd) { window.define(function () { return nThen; }); }
  71. else { window.nThen = nThen; }
  72. /*:: return nThen; */
  73. })();