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