UNPKG

@ama-team/voxengine-sdk

Version:

Bundle of helper functions and classes for VoxEngine scenario scripts

147 lines (134 loc) 3.66 kB
var Future = require('./Future').Future /** * @class * @param {string} message */ function TimeoutException (message) { this.message = message || 'Timeout has exceeded' this.stack = (new Error()).stack } var _ = TimeoutException _.prototype = Object.create(Error.prototype) _.prototype.name = 'TimeoutException' _.prototype.constructor = _ function CancellationException (message) { this.message = message || 'Promise has been cancelled' this.stack = (new Error()).stack } _ = CancellationException _.prototype = Object.create(Error.prototype) _.prototype.name = 'CancellationException' _.prototype.constructor = _ /** * @interface ICancellablePromise * @template T * @extends Thenable.<T> */ /** * @function ICancellablePromise#cancel * * @param {boolean} [silent] Whether to cancel with CancellationException or * just pretend that nothing has happened * * @return ICancellablePromise The very same instance */ /** * @callback timeout~onTimeout * * @param {Function} resolve * @param {Function} reject * @param {TimeoutException} error */ /** * @param {Promise.<*>|Thenable.<*>} promise Promise to add time bound to * @param {int} [timeout] Timeout in milliseconds * @param {timeout~onTimeout|string} [callback] Callback to be run on timeout. * If string is passed, it is used as a message in timeout exception. * @param {string} [message] Error message * @return {ICancellablePromise.<*>} */ function timeout (promise, timeout, callback, message) { if (typeof timeout !== 'number' || timeout < 0) { promise.cancel = function () { return promise } return promise } if (typeof message !== 'string') { message = typeof callback === 'string' ? callback : 'Timeout of ' + timeout + ' ms has exceeded' } if (typeof callback !== 'function') { callback = function (_, reject, error) { reject(error) } } var wrapper = Future.wrap(promise) var bind = setTimeout(function () { var error = callback.length > 2 ? new TimeoutException(message) : null callback(wrapper.resolve, wrapper.reject, error) }, timeout) var cancel = function (silent) { clearTimeout(bind) if (!silent) { wrapper.reject(new CancellationException()) } } wrapper.then(cancel, cancel) wrapper.cancel = function (silent) { cancel(silent) return wrapper } return wrapper } /** * Delays processing of callback for specified time. If no callback is * given, returns empty promise that will resolve in specified time * * @param {int} time * @param {Function} [callback] * * @return {Thenable.<*>} */ function delay (time, callback) { callback = callback || function () {} var target = new Future() var resolve = function () { try { target.resolve(callback()) } catch (e) { target.reject(e) } } var bind = setTimeout(resolve, time) target.cancel = function (silent) { clearTimeout(bind) silent ? resolve() : target.reject(new CancellationException()) return target } return target } /** * Wraps given promise with another one which won't resolve earlier * than specified time. * * @param {Thenable.<*>} promise * @param {int} time Throttle time in milliseconds * @return {Thenable.<*>} */ function throttle (promise, time) { var delayed = delay(time) var target = delayed .then(function () { return promise }) target.cancel = function (silent) { delayed.cancel(silent) return target } return target } module.exports = { timeout: timeout, delay: delay, throttle: throttle, TimeoutException: TimeoutException, CancellationException: CancellationException }