future.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. 'use strict';
  2. /**
  3. * A future similar to Python's asyncio.Future. Allows to resolve or reject
  4. * outside of the executor and query the current status.
  5. */
  6. class Future extends Promise {
  7. constructor(executor) {
  8. const resolve = (...args) => {
  9. this.resolve(...args);
  10. };
  11. const reject = (...args) => {
  12. this.reject(...args);
  13. };
  14. let innerResolve, innerReject;
  15. super((resolveFunc, rejectFunc) => {
  16. innerResolve = resolveFunc;
  17. innerReject = rejectFunc;
  18. if (executor) {
  19. return executor(resolve, reject);
  20. }
  21. });
  22. this._done = false;
  23. console.assert(innerResolve !== undefined && innerReject !== undefined, 'THERE IS NO HOPE!');
  24. this._resolve = innerResolve;
  25. this._reject = innerReject;
  26. }
  27. /**
  28. * Wrap a promise to ensure it does not resolve before a minimum
  29. * duration.
  30. *
  31. * Note: The promise will still reject immediately. Furthermore, be
  32. * aware that the promise does not resolve/reject inside of
  33. * an AngularJS digest cycle.
  34. *
  35. * @param promise the promise or future to be wrapped
  36. * @param minDuration the minimum duration before it should be resolved
  37. * @returns {Future}
  38. */
  39. static withMinDuration(promise, minDuration) {
  40. const start = new Date();
  41. return new Future((resolve, reject) => {
  42. promise
  43. .then((result) => {
  44. const timediff = new Date() - start;
  45. const delay = Math.max(minDuration - timediff, 0);
  46. self.setTimeout(() => resolve(result), delay);
  47. })
  48. .catch((error) => reject(error));
  49. });
  50. }
  51. /**
  52. * Return whether the future is done (resolved or rejected).
  53. */
  54. get done() {
  55. return this._done;
  56. }
  57. /**
  58. * Resolve the future.
  59. */
  60. resolve(...args) {
  61. this._done = true;
  62. return this._resolve(...args);
  63. }
  64. /**
  65. * Reject the future.
  66. */
  67. reject(...args) {
  68. this._done = true;
  69. return this._reject(...args);
  70. }
  71. }