@aplus-frontend/utils
Version:
Utils for Aplus frontend team.
77 lines (73 loc) • 2.29 kB
JavaScript
function runWorker(fn, ...args) {
return new Promise((resolve, reject) => {
const fnString = fn.toString();
const workerScript = `
self.addEventListener('message', async function(e) {
try {
// 将函数字符串转换回函数
const fn = ${fnString};
// 从消息中获取参数
const args = e.data;
// 调用函数并获取结果
const result = fn.apply(null, args);
// 检查结果是否为 Promise
if (result && typeof result.then === 'function') {
// 处理异步函数
try {
const asyncResult = await result;
self.postMessage({ success: true, data: asyncResult });
} catch (asyncError) {
self.postMessage({
success: false,
error: {
message: asyncError.message,
stack: asyncError.stack,
name: asyncError.name
}
});
}
} else {
// 处理同步函数
self.postMessage({ success: true, data: result });
}
} catch (error) {
// 处理执行异常
self.postMessage({
success: false,
error: {
message: error.message,
stack: error.stack,
name: error.name
}
});
}
});`;
const workerBlob = new Blob([workerScript], {
type: "application/javascript"
});
const blobUrl = URL.createObjectURL(workerBlob);
const worker = new Worker(blobUrl);
const cleanupBlobUrl = () => URL.revokeObjectURL(blobUrl);
worker.addEventListener("error", (e) => {
cleanupBlobUrl();
reject(e);
});
worker.addEventListener("message", function(evt) {
cleanupBlobUrl();
const response = evt.data;
if (response.success) {
resolve(response.data);
} else {
const error = new Error(response.error.message);
error.stack = response.error.stack;
error.name = response.error.name;
reject(error);
}
worker.terminate();
});
worker.postMessage(args);
});
}
export {
runWorker
};