当前位置: 首页 > wzjs >正文

深圳做网站行业北京设计公司网站

深圳做网站行业,北京设计公司网站,什么网站从做系统,抚州律师网站建设背景 目前主进程使用 timer.setInterval 来做间隔任务执行,但是总有用户反馈养号卡主不执行了,或者某个操作不执行了,为了排除主进程的运行造成 setInterval 阻塞可能,将 setInterval 单独处理,可以排除主进程对定时器…

背景

目前主进程使用 timer.setInterval 来做间隔任务执行,但是总有用户反馈养号卡主不执行了,或者某个操作不执行了,为了排除主进程的运行造成 setInterval 阻塞可能,将 setInterval 单独处理,可以排除主进程对定时器的影响。

此外,现在每秒定时会造成很多判断动作的浪费(每个人开发时都要做这种判断操作),这就需要一层封装,将自己需要的间隔操作注册到定时服务里面去,在符合条件时再收到该操作,让开发者专注处理自己的逻辑。

Worker 作为定时器的优点

  1. 隔离性:定时任务不会阻塞主线程,主线程可以专注于其他任务。

  2. 可靠性:Worker 线程的定时触发更精准,不受主线程负载影响。

  3. 可管理性:一个统一的 setInterval 管理所有事件,便于扩展和维护。

  4. 模块化:定时逻辑封装在 Worker 中,主进程代码更简洁。

  5. 大规模支持:适合管理大量定时任务,性能开销更可控。

  6. 错误隔离:Worker 的错误不会影响主进程,便于调试。

  7. 复杂逻辑支持:Worker 提供独立环境,适合实现复杂的定时功能。

  8. 线程安全:通过 postMessage 通信,确保事件触发安全。

几个知识点

  1. worker.js 可以用 webpack 配置中 target="node"进行打包处理

  2. npm run dev 时的路径需要用到 process.cwd() 提取,这是 electron 开发环境常规操作

实现步骤

  1. 主进程中引入一个心跳闹钟类,负责存储注册事件以及接收来自 worker 的间隔事件

  2. worker.js 负责接收来自主进程的注册事件,通过一个 setInterval 和求余事件,向主进程这边发送对应事件,主进程的心跳闹钟类会根据注册事件列表,来调度不同的事件下的回调函数,执行具体逻辑。

源代码实现

// HeartbeatClick.js
const { Worker } = require('worker_threads');
const path = require('path');const HEARTBEAT_LOG_PREFIX = '[Main - HeartbeatClock]';class HeartbeatClock {constructor() {this.worker = null;this.eventHandlers = new Map(); // Map<eventName, Array<Function>>this.workerPath = path.join(process.cwd(), 'src', 'main', 'worker/heartbeat.worker.js');}// 启动 Workerstart() {if (this.worker) {console.log(`${HEARTBEAT_LOG_PREFIX} Worker already running.`);return;}this.worker = new Worker(this.workerPath);this.worker.on('message', this.handleWorkerMessage.bind(this));this.worker.on('error', this.handleWorkerError.bind(this));this.worker.on('exit', this.handleWorkerExit.bind(this));console.log(`${HEARTBEAT_LOG_PREFIX} Worker started.`);// 重新注册已有的事件this.eventHandlers.forEach((_, eventName) => {this.worker.postMessage({ type: 'register', eventName });});}// 停止 Workerstop() {if (this.worker) {this.worker.terminate();this.worker = null;console.log(`${HEARTBEAT_LOG_PREFIX} Worker stopped.`);}}// 注册定时事件registerEvent(eventName, handler) {if (!eventName.startsWith('interval:') || !eventName.endsWith('s')) {throw new Error('事件名格式错误,应为 interval:Ns,例如 interval:1s');}if (typeof handler !== 'function') {throw new Error('handler 必须是一个函数');}// 如果事件名不存在,初始化一个空数组if (!this.eventHandlers.has(eventName)) {this.eventHandlers.set(eventName, []);}// 将回调函数添加到数组中const handlers = this.eventHandlers.get(eventName);handlers.push(handler);console.log(`${HEARTBEAT_LOG_PREFIX} Registered handler for event: ${eventName}, total handlers: ${handlers.length}`);// 如果 Worker 已启动,通知 Worker 注册事件if (this.worker) {this.worker.postMessage({ type: 'register', eventName });console.log(`${HEARTBEAT_LOG_PREFIX} Notified worker of event: ${eventName}`);}}// 注销定时事件unregisterEvent(eventName, handler) {if (!this.eventHandlers.has(eventName)) {console.log(`${HEARTBEAT_LOG_PREFIX} Event not found: ${eventName}`);return;}const handlers = this.eventHandlers.get(eventName);// 如果提供了特定的 handler,则只移除该 handlerif (handler && typeof handler === 'function') {const index = handlers.indexOf(handler);if (index !== -1) {handlers.splice(index, 1);console.log(`${HEARTBEAT_LOG_PREFIX} Unregistered specific handler for event: ${eventName}, remaining handlers: ${handlers.length}`);}} else {// 如果未提供 handler,则移除所有 handlerhandlers.length = 0;console.log(`${HEARTBEAT_LOG_PREFIX} Unregistered all handlers for event: ${eventName}`);}// 如果没有 handler 了,删除事件并通知 Workerif (handlers.length === 0) {this.eventHandlers.delete(eventName);if (this.worker) {this.worker.postMessage({ type: 'unregister', eventName });console.log(`${HEARTBEAT_LOG_PREFIX} Notified worker to unregister event: ${eventName}`);}}}// 处理 Worker 发送的消息handleWorkerMessage(message) {if (message.type === 'interval') {const eventName = message.eventName;if (this.eventHandlers.has(eventName)) {const handlers = this.eventHandlers.get(eventName);handlers.forEach((handler, index) => {try {handler();} catch (err) {console.error(`${HEARTBEAT_LOG_PREFIX} Error in handler ${index} for event ${eventName}:`, err);}});} else {console.log(`${HEARTBEAT_LOG_PREFIX} Unregistered event: ${eventName}`);}}}// 处理 Worker 错误handleWorkerError(err) {console.error(`${HEARTBEAT_LOG_PREFIX} Worker error:`, err);}// 处理 Worker 退出handleWorkerExit(code) {console.log(`${HEARTBEAT_LOG_PREFIX} Worker exited with code: ${code}`);this.worker = null;}
}export default HeartbeatClock;// main.js
import HeartbeatClock from './HeartbeatClock';app.on('ready', () => {createMainWindow();const heartbeatClock = new HeartbeatClock();heartbeatClock.start();// 示例:注册定时事件heartbeatClock.registerEvent('interval:1s', () => {console.log('每 1 秒执行的任务 ----- 1', Date.now());});heartbeatClock.registerEvent('interval:1s', () => {console.log('每 1 秒执行的任务 ----- 2', Date.now());});heartbeatClock.registerEvent('interval:1s', () => {console.log('每 1 秒执行的任务 ----- 3', Date.now());});heartbeatClock.registerEvent('interval:3s', () => {console.log('每 3 秒执行的任务', Date.now());});heartbeatClock.registerEvent('interval:5s', () => {console.log('每 5 秒执行的任务', Date.now());});heartbeatClock.registerEvent('interval:10s', () => {console.log('每 10 秒执行的任务', Date.now());});
});// heartbeat.worker.js
const { parentPort } = require('worker_threads');// 存储注册的间隔(秒数)和对应的事件名
const intervals = new Map(); // { intervalSeconds: eventName }
let tickCount = 0; // 计数器,从 0 开始,每秒递增
const tickInterval = 1000; // 1 秒// 每秒递增计数器并检查事件
const ticker = setInterval(() => {tickCount++; // 计数器递增intervals.forEach((eventName, intervalSeconds) => {if (tickCount % intervalSeconds === 0) {console.log(`[Worker] 触发事件: ${eventName}, tickCount: ${tickCount}`);parentPort.postMessage({ type: 'interval', eventName });}});// 可选:防止 tickCount 过大(虽然 JavaScript 数字类型安全,但仍可重置)if (tickCount >= Number.MAX_SAFE_INTEGER) {tickCount = 0;console.log('[Worker] 重置计数器');}
}, tickInterval);// 监听主进程的消息
parentPort.on('message', (message) => {if (message.type === 'register') {const eventName = message.eventName; // 例如 "interval:30s"const intervalSeconds = parseInt(eventName.split(':')[1]); // 解析出秒数,例如 30if (!intervals.has(intervalSeconds)) {intervals.set(intervalSeconds, eventName);console.log(`[Worker] 已注册事件: ${eventName}, interval: ${intervalSeconds}s`);}} else if (message.type === 'unregister') {const eventName = message.eventName;const intervalSeconds = parseInt(eventName.split(':')[1]);if (intervals.has(intervalSeconds)) {intervals.delete(intervalSeconds);console.log(`[Worker] 已注销事件: ${eventName}`);}}
});// 清理逻辑
parentPort.on('close', () => {clearInterval(ticker);intervals.clear();tickCount = 0;console.log('[Worker] 已清理定时器和事件');
});// 处理 Worker 错误
parentPort.on('error', (err) => {console.error('[Worker] 错误:', err);
});


文章转载自:

http://zsU1eH6r.tpwzp.cn
http://0Bdt1fiR.tpwzp.cn
http://4d2JbPI5.tpwzp.cn
http://7vq7f4iU.tpwzp.cn
http://N8nTmHVk.tpwzp.cn
http://iNfs5wbA.tpwzp.cn
http://IMNtNvhz.tpwzp.cn
http://dCTg9fqa.tpwzp.cn
http://VHXe3zvx.tpwzp.cn
http://565L6pEm.tpwzp.cn
http://sdmlpIJn.tpwzp.cn
http://VhJLBLpq.tpwzp.cn
http://7zIN0qMw.tpwzp.cn
http://EKPzUgag.tpwzp.cn
http://FpWXsfMo.tpwzp.cn
http://VTAb5l0a.tpwzp.cn
http://QzUIXB7j.tpwzp.cn
http://EOi0DjJe.tpwzp.cn
http://urdb4t5T.tpwzp.cn
http://Wzz4tvor.tpwzp.cn
http://EaNZNypU.tpwzp.cn
http://mQtPdlU8.tpwzp.cn
http://7yQqp3ei.tpwzp.cn
http://dXzwIOLc.tpwzp.cn
http://8ApQiqRs.tpwzp.cn
http://J4lCodWs.tpwzp.cn
http://jxgPWVRx.tpwzp.cn
http://gVSH91Je.tpwzp.cn
http://ofZMTcpx.tpwzp.cn
http://UU3LuYls.tpwzp.cn
http://www.dtcms.com/wzjs/651591.html

相关文章:

  • wordpress缓存问题seo基础入门视频教程
  • seo网站营销推广全...网站建设专家联系方式
  • 宁波新亚建设内部网站濮阳网站建设在哪里
  • 石家庄做商城网站的公司wordpress-erphpdown
  • 软件开发网站开发学习麦进斗网站建设
  • 龙南网站建设wordpress怎样禁止采集
  • 网站权重是什么意思服务器用来做网站和数据库
  • 常用网站建设工具中国最大的广告公司排名列表
  • 嘉兴网站制作多少钱品牌官方网站建设
  • 做网站有什么要求网站建设费开票收候开在哪个类别里
  • 在线a视频网站一级a做爰片网上自己建网站
  • 网站开发能从事那些职业wordpress悬赏功能
  • 做公司点评的网站产品介绍网站html
  • w网站建设需求说明中国刚刚发生8件大事
  • 网上书城网站系统建设海南响应式网站建设哪里好
  • 淄博网站建设与推广18互联网站做网站程序
  • 互联网与网站有哪些网页设计的主题分析
  • 怎么学做电子商务网站网站建设指南
  • 没有面板的服务器怎么建设网站销售网站免费模板
  • 广东广州免费建站在建设一个公司网站多少钱
  • 厦门建网站费用一览表浙江网络公司排名
  • 孝感网站开发选优搏wordpress更改登录
  • 装修公司网站建设的意义公共体育课程网站建设
  • 天水市住房和城乡建设局网站礼品做便宜的网站
  • 网站开发报价合同株洲静默三天
  • 胶州做网站京东商城网站的搜索引擎营销做的案例分析
  • 百度网站前三名权重一般在多少晋城网站制作公司怎么选
  • 北京建设部官方网站证书查询三亚发布最新消息
  • 做python一个网站苏州网站建设企业网站制作
  • php网站建设基本流程廊坊百度seo公司