runAsync - 运行异步函数advanced
优质
小牛编辑
125浏览
2023-12-01
通过使用 Web Worker 在单独的线程中运行一个函数,允许长时间运行的函数不会阻塞 UI。
使用 Blob
对象URL创建一个新的Worker
,其内容应该是所提供函数的字符串化版本。 立即发送回调用函数的返回值。 返回一个 promise ,监听 onmessage
和 onerror
事件并解析 worker 发回的数据,或者抛出一个错误。
const runAsync = fn => { const blob = `var fn = ${fn.toString()}; postMessage(fn());`; const worker = new Worker( URL.createObjectURL(new Blob([blob]), { type: 'application/javascript; charset=utf-8' }) ); return new Promise((res, rej) => { worker.onmessage = ({ data }) => { res(data), worker.terminate(); }; worker.onerror = err => { rej(err), worker.terminate(); }; }); };
const longRunningFunction = () => { let result = 0; for (let i = 0; i < 1000; i++) { for (let j = 0; j < 700; j++) { for (let k = 0; k < 300; k++) { result = result + i + j + k; } } } return result; }; /* NOTE: Since the function is running in a different context, closures are not supported. The function supplied to `runAsync` gets stringified, so everything becomes literal. All variables and functions must be defined inside. */ runAsync(longRunningFunction).then(console.log); // 209685000000 runAsync(() => 10 ** 3).then(console.log); // 1000 let outsideVariable = 50; runAsync(() => typeof outsideVariable).then(console.log); // 'undefined'