From eff653a972d6bb21ce8033f735898626a366a9d6 Mon Sep 17 00:00:00 2001 From: marcus Date: Fri, 21 Apr 2017 00:22:16 +0200 Subject: [PATCH] ptimized periodic timer support and improved API doc --- API.md | 10 +++++++--- HISTORY.md | 4 ++++ lib/index.js | 43 ++++++++++++++++++++++--------------------- src/index.coffee | 39 ++++++++++++++++++++------------------- 4 files changed, 53 insertions(+), 43 deletions(-) diff --git a/API.md b/API.md index 8be34f0..893d67e 100644 --- a/API.md +++ b/API.md @@ -4,10 +4,14 @@ ## pimatic-plugin-commons API -## settled() +## settled(promise) Waits for a given promise to be resolved or rejected. +### Params: + +* **Promise** *promise* - the promise to wait for + ## series(input, mapper) Maps an array of promises or items to a mapping function resolving or @@ -29,7 +33,7 @@ Calls a function repeatedly, with a fixed time delay between each call ### Params: -* **Function** *func* - function to be called +* **Function** *func* - the function to be called * **Number** *delay* - delay in milliseconds ### Return: @@ -76,7 +80,7 @@ Outputs an error message and optionally rejects a Promise on return. * **Function** *reject* - function to reject a promise on return, may be null * **Error** *error* - error object -* **String** *[customMessage]* - a custom message to be used as prefix to the error message +* **String** *[customMessage]* - a custom message to be used as prefix to the error message ## rejectWithError(reject, error) diff --git a/HISTORY.md b/HISTORY.md index 11ef902..30570e7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Release History +* next release + * Optimized periodic timer support + * Improved API documentation + * 20170420, V0.9.4 * Added periodic timer support which provides better accuracy than setInterval() diff --git a/lib/index.js b/lib/index.js index 2a47661..fed6bdc 100644 --- a/lib/index.js +++ b/lib/index.js @@ -13,6 +13,7 @@ module.exports = function(env) { /* Waits for a given promise to be resolved or rejected. + @param {Promise} promise - the promise to wait for */ settled: function(promise) { return promise.reflect(); @@ -35,39 +36,38 @@ module.exports = function(env) { function call at the next ick rather than starting with timeout delay. Moreover, it adjust the delay time to dispatch periodic calls with higher accuracy than setInterval() does. - @param {Function} func - function to be called + @param {Function} func - the function to be called @param {Number} delay - delay in milliseconds @return {String} the timer id */ setPeriodicTimer: function(func, delay) { - var id, instance, taskHandler; + var id, taskHandler, timerData; id = "setPeriodicTimer." + (++_intervalId); - instance = { + timerData = { func: func, delay: delay, - target: 0 + target: 0, + started: false }; taskHandler = (function(func, delay) { var adjust, elapsed; - if (common._periodicTimers.hasOwnProperty(id)) { - delete common._periodicTimers[id]; - } - if (instance.started == null) { - instance.started = true; - common._periodicTimers[id] = setTimeout(taskHandler, instance.target); + if (!timerData.started) { + timerData.started = true; + common._periodicTimers[id] = setTimeout(taskHandler, timerData.target); } else { - elapsed = instance.delay; - adjust = 0; - if (instance.target === 0) { - instance.target = instance.delay; - instance.startTime = new Date().valueOf() - instance.delay; + if (timerData.target === 0) { + adjust = 0; + timerData.target = timerData.delay; + timerData.startTime = Date.now() - timerData.delay; } else { - elapsed = new Date().valueOf() - instance.startTime; - adjust = instance.target - elapsed; + elapsed = Date.now() - timerData.startTime; + adjust = timerData.target - elapsed; + } + timerData.target += timerData.delay; + if (common._periodicTimers.hasOwnProperty(id)) { + common._periodicTimers[id] = setTimeout(taskHandler, timerData.delay + adjust); + timerData.func(); } - instance.target += instance.delay; - common._periodicTimers[id] = setTimeout(taskHandler, instance.delay + adjust); - instance.func(); } return id; }); @@ -132,7 +132,8 @@ module.exports = function(env) { @param {Function} reject - function to reject a promise on return, may be null @param {Error} error - error object - @param {String} [customMessage] - a custom message to be used as prefix to the error message + @param {String} [customMessage] - a custom message to be used as prefix + to the error message */ rejectWithErrorString: function(reject, error, customMessage) { var message, ref; diff --git a/src/index.coffee b/src/index.coffee index fbeb344..40adb35 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -10,6 +10,7 @@ module.exports = (env) -> ### Waits for a given promise to be resolved or rejected. + @param {Promise} promise - the promise to wait for ### settled: (promise) -> promise.reflect() @@ -28,38 +29,37 @@ module.exports = (env) -> function call at the next ick rather than starting with timeout delay. Moreover, it adjust the delay time to dispatch periodic calls with higher accuracy than setInterval() does. - @param {Function} func - function to be called + @param {Function} func - the function to be called @param {Number} delay - delay in milliseconds @return {String} the timer id ### setPeriodicTimer: (func, delay) -> id = "setPeriodicTimer.#{++_intervalId}" - instance = { + timerData = { func: func delay: delay target: 0 + started: false } taskHandler = ((func, delay) -> - if common._periodicTimers.hasOwnProperty(id) - delete common._periodicTimers[id] - - unless instance.started? - instance.started = true - common._periodicTimers[id] = setTimeout(taskHandler, instance.target) + unless timerData.started + timerData.started = true + common._periodicTimers[id] = setTimeout(taskHandler, timerData.target) else - elapsed = instance.delay - adjust = 0 - if instance.target is 0 - instance.target = instance.delay - instance.startTime = new Date().valueOf() - instance.delay + if timerData.target is 0 + adjust = 0 + timerData.target = timerData.delay + timerData.startTime = Date.now() - timerData.delay else - elapsed = new Date().valueOf() - instance.startTime; - adjust = instance.target - elapsed; + elapsed = Date.now() - timerData.startTime; + adjust = timerData.target - elapsed; + + timerData.target += timerData.delay + if common._periodicTimers.hasOwnProperty(id) + common._periodicTimers[id] = setTimeout(taskHandler, timerData.delay + adjust) + timerData.func() - instance.target += instance.delay - common._periodicTimers[id] = setTimeout(taskHandler, instance.delay + adjust) - instance.func() return id ) return taskHandler(func, delay) @@ -107,7 +107,8 @@ module.exports = (env) -> @param {Function} reject - function to reject a promise on return, may be null @param {Error} error - error object - @param {String} [customMessage] - a custom message to be used as prefix to the error message + @param {String} [customMessage] - a custom message to be used as prefix + to the error message ### rejectWithErrorString: (reject, error="Unknown", customMessage=null) -> message = "" + (error.message ? error)