js简单封装类导出并使用

该文章展示了如何在JavaScript中定义一个类(mask),包含构造函数和toast方法,用于在微信小程序中显示消息提示。类实例化后调用toast方法可显示带有指定标题和图标的提示,持续2秒,并设置有蒙层。

封装一个类

在js文件中定义一个类并导出

class mask {
	constructor(title = '', icon = "none") {
		this.title = title
		this.icon = icon
	}
	// 消息提示框
	toast() {
		wx.showToast({
			title: this.title,
			icon: this.icon,
			duration: 2000,
			mask:true
		})
	}
}
export {mask}

在要使用的文件中引入

import {mask} from '@/common/common.js'

在使用的地方

new mask('测试').toast()

<think> 我们之前已经封装了一个`TimedRequestScheduler`,现在需要将其导出以便在多个模块中使用。 通常,在JavaScript/Node.js中,我们可以使用CommonJS模块(Node.js环境)或ES6模块(浏览器或Node.js环境)来导出和导入。 下面我将分别展示: 1. 在Node.js环境中使用CommonJS模块导出 2. 在支持ES6模块的环境(如现代浏览器或Node.js)中导出 3. 在浏览器中直接通过script标签引入(使用IIFE封装) 我们假设文件名是`TimedRequestScheduler.js`。 ### 方案1: CommonJS模块(Node.js) ```javascript // TimedRequestScheduler.js class TimedRequestScheduler { // ... 之前的实现代码 } module.exports = TimedRequestScheduler; ``` 使用方式(在另一个Node.js文件中): ```javascript const TimedRequestScheduler = require('./TimedRequestScheduler'); const scheduler = new TimedRequestScheduler(); ``` ### 方案2: ES6模块 ```javascript // TimedRequestScheduler.js export default class TimedRequestScheduler { // ... 之前的实现代码 } ``` 使用方式(在另一个ES6模块中): ```javascript import TimedRequestScheduler from './TimedRequestScheduler.js'; const scheduler = new TimedRequestScheduler(); ``` ### 方案3: 浏览器环境(通过script标签引入) 我们可以将封装在一个立即执行函数表达式(IIFE)中,将其附加到全局对象(如window)上。 ```javascript // TimedRequestScheduler.js (function (global) { class TimedRequestScheduler { // ... 之前的实现代码 } // 暴露到全局 global.TimedRequestScheduler = TimedRequestScheduler; })(window || this || {}); // 兼容不同环境 ``` 在HTML中使用: ```html <script src="TimedRequestScheduler.js"></script> <script> const scheduler = new TimedRequestScheduler(); // 添加任务等... </script> ``` ### 完整代码(ES6模块导出示例) 以下是完整的`TimedRequestScheduler`,以ES6模块方式导出: ```javascript // TimedRequestScheduler.js export default class TimedRequestScheduler { constructor() { this.tasks = new Map(); this.taskQueue = []; this.maxConcurrent = 3; this.activeRequests = 0; this.defaultRetry = 2; this.defaultTimeout = 8000; } addServiceTask(id, serviceCall, interval, options = {}) { if (this.tasks.has(id)) { console.warn(`任务ID ${id} 已存在,将被替换`); this.removeServiceTask(id); } const task = { id, serviceCall, interval, retryCount: options.retryCount || this.defaultRetry, timeout: options.timeout || this.defaultTimeout, onSuccess: options.onSuccess || (() => {}), onError: options.onError || (() => {}), timerId: null, lastRun: null, nextRun: null, errorCount: 0 }; this.tasks.set(id, task); this.scheduleTask(id); return id; } scheduleTask(id) { const task = this.tasks.get(id); if (!task) return; if (task.timerId) clearTimeout(task.timerId); const now = Date.now(); const nextRun = task.lastRun ? task.lastRun + task.interval : now; task.timerId = setTimeout(() => { this.executeTask(id); }, Math.max(0, nextRun - now)); task.nextRun = nextRun; } async executeTask(id) { const task = this.tasks.get(id); if (!task) return; task.lastRun = Date.now(); this.scheduleTask(id); if (this.activeRequests >= this.maxConcurrent) { this.taskQueue.push(id); return; } this.activeRequests++; try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), task.timeout); const result = await task.serviceCall({ signal: controller.signal }); clearTimeout(timeoutId); task.onSuccess(result); task.errorCount = 0; } catch (error) { // 注意:这里需要清除timeoutId,但上面catch块中无法直接访问,因此需要在try块外定义timeoutId // 为了解决这个问题,我们可以将timeoutId定义在try块之前 // 修改:将timeoutId的声明移到try外部 } finally { // 但上面的catch块中没有timeoutId,所以我们需要调整结构 // 下面我们重构一下try-catch结构 } // 重构后的执行部分: let timeoutId; try { const controller = new AbortController(); timeoutId = setTimeout(() => controller.abort(), task.timeout); const result = await task.serviceCall({ signal: controller.signal }); clearTimeout(timeoutId); task.onSuccess(result); task.errorCount = 0; } catch (error) { if (timeoutId) clearTimeout(timeoutId); task.errorCount++; if (task.errorCount <= task.retryCount) { console.warn(`任务 ${id} 失败,将重试 (${task.errorCount}/${task.retryCount})`); setTimeout(() => this.executeTask(id), 1000); } else { task.onError(error); task.errorCount = 0; } } finally { this.activeRequests--; if (this.taskQueue.length > 0 && this.activeRequests < this.maxConcurrent) { const nextId = this.taskQueue.shift(); this.executeTask(nextId); } } } removeServiceTask(id) { const task = this.tasks.get(id); if (task && task.timerId) { clearTimeout(task.timerId); } this.tasks.delete(id); const index = this.taskQueue.indexOf(id); if (index !== -1) this.taskQueue.splice(index, 1); } getTaskStatus() { return Array.from(this.tasks.values()).map(task => ({ id: task.id, nextRun: task.nextRun, lastRun: task.lastRun, errorCount: task.errorCount, interval: task.interval })); } pauseAll() { for (const task of this.tasks.values()) { if (task.timerId) { clearTimeout(task.timerId); task.timerId = null; } } } resumeAll() { for (const task of this.tasks.values()) { if (!task.timerId) { this.scheduleTask(task.id); } } } } ``` ### 注意事项 1. **环境兼容性**: - 在浏览器中使用时注意`AbortController`兼容性(现代浏览器支持) - Node.js环境需要15.0以上版本才支持`AbortController`(或使用`node-fetch`等库) 2. **错误处理**: - 重构了`executeTask`方法中的错误处理,确保能清除超时定时器 3. **内存管理**: - 移除任务时清理定时器,避免内存泄漏 ### 使用示例(浏览器ES6模块) ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>定时任务调度器</title> <script type="module"> import TimedRequestScheduler from './TimedRequestScheduler.js'; const scheduler = new TimedRequestScheduler(); // 添加任务示例 scheduler.addServiceTask('example-task', async () => { console.log('任务执行中...'); return { data: 'success' }; }, 2000, { onSuccess: (res) => console.log('成功:', res.data), onError: (err) => console.error('失败:', err) }); </script> </head> <body> </body> </html> ``` ### 相关说明 - 在Node.js使用时,如果版本低于15.0,可以使用`const { AbortController } = require('abort-controller');`安装`abort-controller`包 - 在旧版浏览器中,如果需要支持`AbortController`,可以使用polyfill:`npm install abortcontroller-polyfill` §§相关问题§§: 1. 如何在Node.js低版本中实现请求超时控制 2. 如何扩展定时任务调度器支持循环策略(如每天固定时间执行) 3. 如何实现定时任务的持久化存储(如保存到localStorage) 4. 如何在定时任务调度器中加入任务依赖关系 </think># 定时任务调度器的封装与使用 我将为您展示如何封装之前实现的定时任务调度器通过多种方式导出使用它。 ## 完整的 TimedRequestScheduler 封装 ```javascript // timed-request-scheduler.js class TimedRequestScheduler { constructor(options = {}) { this.tasks = new Map(); this.taskQueue = []; this.activeRequests = 0; // 配置项 this.maxConcurrent = options.maxConcurrent || 3; this.defaultRetry = options.defaultRetry || 2; this.defaultTimeout = options.defaultTimeout || 8000; this.retryDelay = options.retryDelay || 1000; this.logger = options.logger || console; } addServiceTask(id, serviceCall, interval, options = {}) { if (this.tasks.has(id)) { this.logger.warn(`任务ID ${id} 已存在,将被替换`); this.removeServiceTask(id); } const task = { id, serviceCall, interval, retryCount: options.retryCount || this.defaultRetry, timeout: options.timeout || this.defaultTimeout, onSuccess: options.onSuccess || (() => {}), onError: options.onError || (() => {}), onRetry: options.onRetry || (() => {}), timerId: null, lastRun: null, nextRun: null, errorCount: 0, status: 'pending' }; this.tasks.set(id, task); this.scheduleTask(id); return id; } scheduleTask(id) { const task = this.tasks.get(id); if (!task) return; if (task.timerId) clearTimeout(task.timerId); const now = Date.now(); const nextRun = task.lastRun ? task.lastRun + task.interval : now; task.timerId = setTimeout(() => { this.executeTask(id); }, Math.max(0, nextRun - now)); task.nextRun = nextRun; task.status = 'scheduled'; } async executeTask(id) { const task = this.tasks.get(id); if (!task) return; task.lastRun = Date.now(); task.status = 'running'; this.scheduleTask(id); if (this.activeRequests >= this.maxConcurrent) { this.taskQueue.push(id); task.status = 'queued'; return; } this.activeRequests++; let timeoutId; try { const controller = new AbortController(); timeoutId = setTimeout(() => controller.abort(), task.timeout); task.status = 'executing'; const result = await task.serviceCall({ signal: controller.signal }); clearTimeout(timeoutId); task.onSuccess(result); task.errorCount = 0; task.status = 'completed'; } catch (error) { if (timeoutId) clearTimeout(timeoutId); task.errorCount++; if (task.errorCount <= task.retryCount) { this.logger.warn(`任务 ${id} 失败,将重试 (${task.errorCount}/${task.retryCount})`); task.onRetry(error, task.errorCount); task.status = 'retrying'; // 使用指数退避策略 const backoffDelay = this.retryDelay * Math.pow(2, task.errorCount - 1); setTimeout(() => this.executeTask(id), backoffDelay); } else { task.onError(error); task.errorCount = 0; task.status = 'failed'; } } finally { this.activeRequests--; // 检查队列中等待的任务 if (this.taskQueue.length > 0 && this.activeRequests < this.maxConcurrent) { const nextId = this.taskQueue.shift(); this.executeTask(nextId); } } } removeServiceTask(id) { const task = this.tasks.get(id); if (task && task.timerId) { clearTimeout(task.timerId); } this.tasks.delete(id); const index = this.taskQueue.indexOf(id); if (index !== -1) this.taskQueue.splice(index, 1); } getTask(id) { return this.tasks.get(id); } getAllTasks() { return Array.from(this.tasks.values()); } pauseAll() { for (const task of this.tasks.values()) { if (task.timerId) { clearTimeout(task.timerId); task.timerId = null; task.status = 'paused'; } } } resumeAll() { for (const task of this.tasks.values()) { if (!task.timerId) { this.scheduleTask(task.id); } } } } // 导出方式 1: CommonJS (Node.js) if (typeof module !== 'undefined' && module.exports) { module.exports = TimedRequestScheduler; } // 导出方式 2: ES6 模块 if (typeof exports !== 'undefined') { exports.default = TimedRequestScheduler; } // 导出方式 3: 全局变量 (浏览器环境) if (typeof window !== 'undefined') { window.TimedRequestScheduler = TimedRequestScheduler; } ``` ## 使用示例 ### 在 Node.js使用 (CommonJS) ```javascript // app.js const TimedRequestScheduler = require('./timed-request-scheduler'); // 创建调度器实例 const scheduler = new TimedRequestScheduler({ maxConcurrent: 5, defaultRetry: 3 }); // 添加天气服务任务 scheduler.addServiceTask('weather', async ({ signal }) => { const response = await fetch('https://api.weather.com/v1/current?city=beijing', { signal }); if (!response.ok) throw new Error('天气服务请求失败'); return response.json(); }, 60000, { onSuccess: (data) => console.log(`当前温度: ${data.temperature}℃`), onError: (err) => console.error('天气服务错误:', err.message), retryCount: 5 }); // 添加股票服务任务 scheduler.addServiceTask('stock', async ({ signal }) => { const response = await fetch('https://api.stock.com/v1/quote/AAPL', { signal }); if (!response.ok) throw new Error('股票服务请求失败'); return response.json(); }, 30000, { onSuccess: (data) => console.log(`苹果股价: $${data.price}`), onError: (err) => console.error('股票服务错误:', err.message) }); // 10分钟后停止所有任务 setTimeout(() => { scheduler.pauseAll(); console.log('所有任务已暂停'); }, 600000); ``` ### 在浏览器中使用 (ES6 模块) ```html <!-- index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>定时任务调度器示例</title> <script type="module"> import TimedRequestScheduler from './timed-request-scheduler.js'; // 创建调度器实例 const scheduler = new TimedRequestScheduler({ maxConcurrent: 2, logger: { log: console.log, warn: console.warn, error: console.error } }); // 添加用户数据服务 scheduler.addServiceTask('user-service', async ({ signal }) => { const response = await fetch('https://jsonplaceholder.typicode.com/users/1', { signal }); if (!response.ok) throw new Error('用户服务请求失败'); return response.json(); }, 5000, { onSuccess: (data) => { document.getElementById('user-data').innerHTML = ` <h3>用户信息</h3> <p>姓名: ${data.name}</p> <p>邮箱: ${data.email}</p> `; }, onError: (err) => console.error('用户服务错误:', err.message) }); // 添加帖子数据服务 scheduler.addServiceTask('post-service', async ({ signal }) => { const response = await fetch('https://jsonplaceholder.typicode.com/posts/1', { signal }); if (!response.ok) throw new Error('帖子服务请求失败'); return response.json(); }, 7000, { onSuccess: (data) => { document.getElementById('post-data').innerHTML = ` <h3>帖子信息</h3> <p>标题: ${data.title}</p> <p>内容: ${data.body}</p> `; }, onError: (err) => console.error('帖子服务错误:', err.message) }); // 添加任务状态监控 setInterval(() => { const statusDiv = document.getElementById('task-status'); const tasks = scheduler.getAllTasks(); statusDiv.innerHTML = '<h3>任务状态监控</h3>'; tasks.forEach(task => { statusDiv.innerHTML += ` <div class="task"> <strong>${task.id}</strong>: <span>状态: ${task.status}</span>, <span>下次运行: ${task.nextRun ? new Date(task.nextRun).toLocaleTimeString() : 'N/A'}</span>, <span>错误计数: ${task.errorCount}</span> </div> `; }); }, 1000); </script> <style> .task { margin: 10px 0; padding: 10px; border: 1px solid #ddd; border-radius: 4px; } #user-data, #post-data, #task-status { margin: 20px 0; padding: 15px; border: 1px solid #eee; } </style> </head> <body> <h1>定时任务调度器示例</h1> <div id="user-data">加载用户数据中...</div> <div id="post-data">加载帖子数据中...</div> <div id="task-status">加载任务状态中...</div> <button id="pause-btn">暂停所有任务</button> <button id="resume-btn">恢复所有任务</button> <script> document.getElementById('pause-btn').addEventListener('click', () => { scheduler.pauseAll(); alert('所有任务已暂停'); }); document.getElementById('resume-btn').addEventListener('click', () => { scheduler.resumeAll(); alert('所有任务已恢复'); }); </script> </body> </html> ``` ### 在浏览器中使用 (全局变量) ```html <!-- index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>定时任务调度器示例</title> <script src="timed-request-scheduler.js"></script> <script> // 创建调度器实例 const scheduler = new TimedRequestScheduler(); // 添加服务任务 scheduler.addServiceTask('time-service', () => { return new Promise(resolve => { setTimeout(() => { const now = new Date(); document.getElementById('current-time').textContent = `当前时间: ${now.toLocaleTimeString()}`; resolve(now); }, 500); }); }, 1000, { onSuccess: (time) => console.log('时间更新成功:', time) }); </script> </head> <body> <h1>当前时间</h1> <div id="current-time">加载中...</div> </body> </html> ``` ## 关键功能说明 1. **灵活的导出方式**: - 支持 CommonJS (Node.js) - 支持 ES6 模块 (现代浏览器) - 支持全局变量 (传统浏览器) 2. **配置选项**: - `maxConcurrent`: 最大发请求数 - `defaultRetry`: 默认重试次数 - `defaultTimeout`: 默认请求超时时间 - `retryDelay`: 重试延迟基数 - `logger`: 自定义日志记录器 3. **任务状态管理**: - `pending`: 任务已添加但未调度 - `scheduled`: 任务已调度 - `queued`: 任务在队列中等待 - `running`: 任务开始执行 - `executing`: 请求正在进行 - `completed`: 任务成功完成 - `retrying`: 任务正在重试 - `failed`: 任务最终失败 - `paused`: 任务已暂停 4. **高级特性**: - 指数退避重试策略 - 发控制 - 任务队列管理 - 任务状态监控 - 暂停/恢复功能 ## 使用场景建议 1. **实时数据仪表盘**:定期从多个API获取数据更新UI 2. **后台同步任务**:定期同步本地数据到服务器 3. **健康检查系统**:监控多个服务的可用性 4. **价格监控**:定期检查商品价格变化 5. **新闻聚合**:从多个来源定期获取最新新闻
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值