@enact/core
Version:
Enact is an open source JavaScript framework containing everything you need to create a fast, scalable mobile or web application.
276 lines (275 loc) • 10.5 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.Job = void 0;
var _invariant = _interopRequireDefault(require("invariant"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
* Provides a convenient way to manage timed execution of functions.
*
* @class Job
* @memberof core/util
* @public
*/
var Job = exports.Job = /*#__PURE__*/function () {
/**
* @constructor
* @param {Function} fn Function to execute as the requested job.
* @param {Number} timeout The number of milliseconds to wait before starting the job.
*
* @memberof core/util.Job.prototype
*/
function Job(fn, _timeout) {
var _this = this;
_classCallCheck(this, Job);
this.id = null;
this.fn = null;
this.timeout = null;
this.type = null;
/**
* Starts the job.
*
* @method
* @param {...*} [args] Any args passed are forwarded to the callback
*
* @returns {undefined}
* @memberof core/util.Job.prototype
* @public
*/
this.start = function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this.startAfter.apply(_this, [_this.timeout].concat(args));
};
/**
* Starts the job in `timeout` milliseconds
*
* @method
* @param {Number} timeout The number of milliseconds to wait before starting the job.
* This supersedes the timeout set at construction.
* @param {...*} [args] Any args passed are forwarded to the callback
*
* @returns {undefined}
* @memberof core/util.Job.prototype
* @public
*/
this.startAfter = function (timeout) {
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
_this.stop();
_this.type = 'timeout';
_this.id = setTimeout(function () {
return _this.run(args);
}, timeout);
};
/**
* Stops the job.
*
* @method
*
* @returns {undefined}
* @memberof core/util.Job.prototype
* @public
*/
this.stop = function () {
if (_this.id) {
if (_this.type === 'idle') {
window.cancelIdleCallback(_this.id);
} else if (_this.type === 'raf') {
window.cancelAnimationFrame(_this.id);
} else if (_this.type === 'timeout') {
clearTimeout(_this.id);
}
_this.id = _this.type = null;
}
};
/**
* Executes the job immediately, then prevents any other calls to `throttle()` from running
* until the `timeout` configured at construction passes.
*
* @method
* @param {...*} args Any args passed are forwarded to the callback
*
* @returns {undefined}
* @memberof core/util.Job.prototype
* @public
*/
this.throttle = function () {
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
_this.throttleUntil.apply(_this, [_this.timeout].concat(args));
};
/**
* Executes the job immediately, then prevents any other calls to `throttle()` from running for
* `timeout` milliseconds.
*
* @method
* @param {Number} timeout The number of milliseconds to wait before allowing the job to
* be ran again. This supersedes the timeout set at construction.
* @param {...*} [args] Any args passed are forwarded to the callback
*
* @returns {undefined}
* @memberof core/util.Job.prototype
* @public
*/
this.throttleUntil = function (timeout) {
if (!_this.id) {
_this.type = 'timeout';
for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
args[_key4 - 1] = arguments[_key4];
}
_this.run(args);
_this.id = setTimeout(_this.stop, timeout);
}
};
/**
* Executes job when the CPU is idle.
*
* @method
* @param {...*} [args] Any args passed are forwarded to the callback
*
* @returns {undefined}
* @memberof core/util.Job.prototype
* @public
*/
this.idle = function () {
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
args[_key5] = arguments[_key5];
}
_this.idleUntil.apply(_this, [null].concat(args));
};
/**
* Executes job when the CPU is idle, or when the timeout is reached, whichever occurs first.
*
* @method
* @param {Number} timeout The number of milliseconds to wait before executing the
* job. This guarantees that the job is run, if a positive value
* is specified.
* @param {...*} [args] Any args passed are forwarded to the callback
*
* @returns {undefined}
* @memberof core/util.Job.prototype
* @public
*/
this.idleUntil = function (timeout) {
for (var _len6 = arguments.length, args = new Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) {
args[_key6 - 1] = arguments[_key6];
}
if (typeof window !== 'undefined' && window.requestIdleCallback) {
_this.stop();
_this.type = 'idle';
_this.id = window.requestIdleCallback(function () {
return _this.run(args);
}, {
timeout: timeout
});
} else {
// since we can't request an idle callback, just pass to startAfter()
_this.startAfter.apply(_this, [timeout].concat(args));
}
};
/**
* Executes job before the next repaint.
*
* @method
* @param {...*} [args] Any args passed are forwarded to the callback
*
* @returns {undefined}
* @memberof core/util.Job.prototype
* @public
*/
this.startRaf = function () {
for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
args[_key7] = arguments[_key7];
}
_this.startRafAfter.apply(_this, [_this.timeout].concat(args));
};
/**
* Executes job before the next repaint after a given amount of timeout.
*
* @method
* @param {Number} timeout The number of milliseconds to wait before running `requestAnimationFrame`.
* @param {...*} [args] Any args passed are forwarded to the callback
*
* @returns {undefined}
* @memberof core/util.Job.prototype
* @public
*/
this.startRafAfter = function (timeout) {
for (var _len8 = arguments.length, args = new Array(_len8 > 1 ? _len8 - 1 : 0), _key8 = 1; _key8 < _len8; _key8++) {
args[_key8 - 1] = arguments[_key8];
}
_this.type = 'raf';
if (typeof window !== 'undefined') {
var time = null;
var _callback = function callback(timestamp) {
if (time === null) {
time = timestamp;
}
if (timeout && timestamp - time < timeout) {
_this.id = window.requestAnimationFrame(_callback);
} else {
time = null;
_this.run(args);
window.cancelAnimationFrame(_this.id);
_this.id = null;
}
};
_this.id = window.requestAnimationFrame(_callback);
} else {
// If requestAnimationFrame is not supported just run the function immediately
_this.run(args);
}
};
/**
* Starts the job when `promise` resolves.
*
* The job execution is tied to the resolution of the last `Promise` passed. Like other methods
* on `Job`, calling `promise()` again with a new `Promise` will block execution of the job
* until that new `Promise` resolves. Any previous `Promise`s will still resolve normally but
* will not trigger job execution.
*
* Unlike other methods on `Job`, `promise()` returns a `Promise` which is the result of calling
* `then()` on the passed `promise`. That `Promise` resolves with either the result of job
* execution or `undefined` if `Promise` was superseded by a subsequent `Promise` passed as
* described above.
*
* @method
* @param {Promise} promise The promise that must resolve before the job is executed
*
* @returns {Promise}
* @memberof core/util.Job.prototype
* @public
*/
this.promise = function (promise) {
!(promise && typeof promise.then === 'function') ? process.env.NODE_ENV !== "production" ? (0, _invariant["default"])(false, 'promise expects a thenable') : (0, _invariant["default"])(false) : void 0;
_this.type = 'promise';
_this.id = promise;
return promise.then(function (result) {
if (_this.id === promise) {
_this.stop();
return _this.run([result]);
}
});
};
this.fn = fn;
this.timeout = _timeout;
}
return _createClass(Job, [{
key: "run",
value: function run(args) {
// don't want to inadvertently apply Job's context on `fn`
return this.fn.apply(null, args);
}
}]);
}();
var _default = exports["default"] = Job;
;