futoin-asyncsteps
Version:
Mimic traditional threads in single threaded event loop
132 lines (121 loc) • 3.57 kB
JavaScript
;
/**
* @file
* @author Andrey Galkin <andrey@futoin.org>
*
*
* Copyright 2014-2017 FutoIn Project (https://futoin.org)
* Copyright 2014-2017 Andrey Galkin <andrey@futoin.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Neutral interface to event scheduler
* @member AsyncTool
*/
exports = module.exports = {};
/* istanbul ignore if */
if (typeof setImmediate === 'undefined') {
// Wrapper for simple setTimeout
// ---
exports.callLater = function (func, timeout_ms) {
return setTimeout(func, timeout_ms);
};
exports.cancelCall = function (func) {
return clearTimeout(func);
};
// Workaround for security-delayed setTimeout
// ---
// workaround possible multiple instances of AsyncSteps
window._FutoInEventLoopQueue = window._FutoInEventLoopQueue || [];
var TIME_LIMIT = 10; // support browser with 100ms precision
var queue = window._FutoInEventLoopQueue;
var performance = window.performance;
var process_handle = null;
var sched_immed_process = function sched_immed_process() {
if (process_handle) {
clearTimeout(process_handle);
}
process_handle = setTimeout(process_queue, 0);
};
var process_queue = function process_queue() {
process_handle = null;
var end_time = performance.now() + TIME_LIMIT;
while (queue.length) {
var r = queue.shift();
try {
r();
} catch (e) {
sched_immed_process();
throw e;
}
if (performance.now() >= end_time) {
sched_immed_process();
break;
}
}
};
exports.callImmediate = function (func) {
if (!queue.length) {
sched_immed_process();
}
var handle = function handle() {
func();
}; // same func can be added multiple times
queue.push(handle);
return handle;
};
exports.cancelImmediate = function (handle) {
var i = queue.indexOf(handle);
if (i >= 0) {
queue.splice(i, 1);
}
};
} else {
/**
* Wrapper for setTimeout()
* @param {Function} func - callback to execute
* @param {number} [timeout_ms] - optional timeout in ms
* @returns {object} - timer handle
* @alias AsyncTool.callLater
*/
exports.callLater = function (func, timeout_ms) {
return setTimeout(func, timeout_ms);
};
/**
* Wrapper for clearTimeout()/clearImmediate()
* @param {object} handle - Handle returned from AsyncTool.callLater
* @alias AsyncTool.cancelCall
*/
exports.cancelCall = function (handle) {
clearTimeout(handle);
};
/**
* Wrapper for setImmediate()
* @param {Function} func - callback to execute
* @returns {object} - timer handle
* @alias AsyncTool.callImmediate
*/
exports.callImmediate = function (func) {
return setImmediate(func);
};
/**
* Wrapper for clearImmediate()
* @param {object} handle - Handle returned from AsyncTool.callImmediate
* @alias AsyncTool.cancelImmediate
*/
exports.cancelImmediate = function (handle) {
clearImmediate(handle);
};
}
//# sourceMappingURL=AsyncTool.js.map