UNPKG

billboard.js

Version:

Re-usable easy interface JavaScript chart library, based on D3 v4+

116 lines (99 loc) 2.63 kB
/** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ import {window} from "./browser"; // Store blob in memory const blob = {}; /** * Get Object URL * @param {Function} fn Function to be executed in worker * @param {Array} depsFn Dependency functions to run given function(fn). * @returns {string} * @private */ function getObjectURL(fn: Function, depsFn?: Function[]): string { const fnString = fn.toString(); const key = fnString.replace(/(function|[\s\W\n])/g, "").substring(0, 15); if (!(key in blob)) { // Web Worker body blob[key] = new window.Blob([ `${depsFn?.map(String).join(";") ?? ""} self.onmessage=function({data}) { const result = (${fnString}).apply(null, data); self.postMessage(result); };` ], { type: "text/javascript" }); } return window.URL.createObjectURL(blob[key]); } /** * Get WebWorker instance * @param {string} src URL object as string * @returns {object} WebWorker instance * @private */ export function getWorker(src) { const worker = new window.Worker(src); // handle error worker.onerror = function(e) { // eslint-disable-next-line no-console console.error ? console.error(e) : console.log(e); }; return worker; } /** * Create and run on Web Worker * @param {boolean} useWorker Use Web Worker * @param {Function} fn Function to be executed in worker * @param {Function} callback Callback function to receive result from worker * @param {Array} depsFn Dependency functions to run given function(fn). * @returns {object} * @example * const worker = runWorker(function(arg) { * // do some tasks... * console.log("param:", A(arg)); * * return 1234; * }, function(data) { * // callback after worker is done * console.log("result:", data); * }, * [function A(){}] * ); * * worker(11111); * @private */ export function runWorker( useWorker = true, fn: Function, callback: Function, depsFn?: Function[] ): Function { let runFn = function(...args) { const res = fn(...args); callback(res); }; if (window.Worker && useWorker) { const src = getObjectURL(fn, depsFn); const worker = getWorker(src); runFn = function(...args) { // trigger worker worker.postMessage(args); // listen worker worker.onmessage = function(e) { // release object URL from memory window.URL.revokeObjectURL(src); return callback(e.data); }; // return new Promise((resolve, reject) => { // worker.onmessage = ({data}) => resolve(data); // worker.onerror = reject; // }); }; } return runFn; }