timers.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. "use strict";
  2. module.exports = function(Promise, INTERNAL, debug) {
  3. var util = require("./util");
  4. var TimeoutError = Promise.TimeoutError;
  5. function HandleWrapper(handle) {
  6. this.handle = handle;
  7. }
  8. HandleWrapper.prototype._resultCancelled = function() {
  9. clearTimeout(this.handle);
  10. };
  11. var afterValue = function(value) { return delay(+this).thenReturn(value); };
  12. var delay = Promise.delay = function (ms, value) {
  13. var ret;
  14. var handle;
  15. if (value !== undefined) {
  16. ret = Promise.resolve(value)
  17. ._then(afterValue, null, null, ms, undefined);
  18. if (debug.cancellation() && value instanceof Promise) {
  19. ret._setOnCancel(value);
  20. }
  21. } else {
  22. ret = new Promise(INTERNAL);
  23. handle = setTimeout(function() { ret._fulfill(); }, +ms);
  24. if (debug.cancellation()) {
  25. ret._setOnCancel(new HandleWrapper(handle));
  26. }
  27. }
  28. ret._setAsyncGuaranteed();
  29. return ret;
  30. };
  31. Promise.prototype.delay = function (ms) {
  32. return delay(ms, this);
  33. };
  34. var afterTimeout = function (promise, message, parent) {
  35. var err;
  36. if (typeof message !== "string") {
  37. if (message instanceof Error) {
  38. err = message;
  39. } else {
  40. err = new TimeoutError("operation timed out");
  41. }
  42. } else {
  43. err = new TimeoutError(message);
  44. }
  45. util.markAsOriginatingFromRejection(err);
  46. promise._attachExtraTrace(err);
  47. promise._reject(err);
  48. if (parent != null) {
  49. parent.cancel();
  50. }
  51. };
  52. function successClear(value) {
  53. clearTimeout(this.handle);
  54. return value;
  55. }
  56. function failureClear(reason) {
  57. clearTimeout(this.handle);
  58. throw reason;
  59. }
  60. Promise.prototype.timeout = function (ms, message) {
  61. ms = +ms;
  62. var ret, parent;
  63. var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() {
  64. if (ret.isPending()) {
  65. afterTimeout(ret, message, parent);
  66. }
  67. }, ms));
  68. if (debug.cancellation()) {
  69. parent = this.then();
  70. ret = parent._then(successClear, failureClear,
  71. undefined, handleWrapper, undefined);
  72. ret._setOnCancel(handleWrapper);
  73. } else {
  74. ret = this._then(successClear, failureClear,
  75. undefined, handleWrapper, undefined);
  76. }
  77. return ret;
  78. };
  79. };