timers.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. ret._captureStackTrace();
  28. }
  29. ret._setAsyncGuaranteed();
  30. return ret;
  31. };
  32. Promise.prototype.delay = function (ms) {
  33. return delay(ms, this);
  34. };
  35. var afterTimeout = function (promise, message, parent) {
  36. var err;
  37. if (typeof message !== "string") {
  38. if (message instanceof Error) {
  39. err = message;
  40. } else {
  41. err = new TimeoutError("operation timed out");
  42. }
  43. } else {
  44. err = new TimeoutError(message);
  45. }
  46. util.markAsOriginatingFromRejection(err);
  47. promise._attachExtraTrace(err);
  48. promise._reject(err);
  49. if (parent != null) {
  50. parent.cancel();
  51. }
  52. };
  53. function successClear(value) {
  54. clearTimeout(this.handle);
  55. return value;
  56. }
  57. function failureClear(reason) {
  58. clearTimeout(this.handle);
  59. throw reason;
  60. }
  61. Promise.prototype.timeout = function (ms, message) {
  62. ms = +ms;
  63. var ret, parent;
  64. var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() {
  65. if (ret.isPending()) {
  66. afterTimeout(ret, message, parent);
  67. }
  68. }, ms));
  69. if (debug.cancellation()) {
  70. parent = this.then();
  71. ret = parent._then(successClear, failureClear,
  72. undefined, handleWrapper, undefined);
  73. ret._setOnCancel(handleWrapper);
  74. } else {
  75. ret = this._then(successClear, failureClear,
  76. undefined, handleWrapper, undefined);
  77. }
  78. return ret;
  79. };
  80. };