1. JavaScript常用技巧解析
JavaScript作为现代Web开发的基石语言,掌握其核心技巧能显著提升开发效率。本文将分享一些在实际项目中验证过的高效JavaScript编码技巧,这些方法不仅能解决常见问题,还能优化代码性能。
1.1 数组操作的高阶用法
数组是JavaScript中最常用的数据结构之一,熟练运用数组方法可以写出更简洁的代码:
// 快速去重 const uniqueArray = [...new Set([1, 2, 2, 3, 4, 4])]; console.log(uniqueArray); // [1, 2, 3, 4] // 数组扁平化 const nestedArray = [1, [2, [3, [4]]]]; const flatArray = nestedArray.flat(Infinity); console.log(flatArray); // [1, 2, 3, 4] // 数组分组 const groupBy = (array, key) => { return array.reduce((acc, obj) => { const property = obj[key]; acc[property] = acc[property] || []; acc[property].push(obj); return acc; }, {}); };提示:现代JavaScript引擎对原生数组方法进行了深度优化,相比手动实现的循环,使用map/filter/reduce等内置方法通常性能更好。
1.2 对象处理技巧
对象操作是JavaScript开发中的日常任务,这些技巧能帮你处理复杂场景:
// 对象属性动态访问 const getValue = (obj, path) => path.split('.').reduce((acc, key) => acc?.[key], obj); // 深拷贝对象 const deepClone = obj => JSON.parse(JSON.stringify(obj)); // 合并对象并保留原型链 const mergeWithPrototype = (target, ...sources) => { sources.forEach(source => { Object.getOwnPropertyNames(source).forEach(prop => { Object.defineProperty( target, prop, Object.getOwnPropertyDescriptor(source, prop) ); }); }); return target; };2. 异步编程实战技巧
现代JavaScript开发离不开异步编程,以下是处理异步操作的实用方法:
2.1 Promise高级用法
// Promise重试机制 const retry = (fn, retries = 3, delay = 1000) => new Promise((resolve, reject) => { fn() .then(resolve) .catch(err => { if (retries <= 1) return reject(err); setTimeout(() => retry(fn, retries - 1, delay).then(resolve).catch(reject), delay); }); }); // 并行控制 const parallelLimit = (tasks, limit) => { const results = []; let current = 0; return new Promise((resolve) => { function run() { if (current >= tasks.length) { if (results.length === tasks.length) resolve(results); return; } const index = current++; tasks[index]() .then(res => { results[index] = res; run(); }) .catch(err => { results[index] = err; run(); }); } for (let i = 0; i < Math.min(limit, tasks.length); i++) { run(); } }); };2.2 async/await优化
// 错误处理包装器 const asyncHandler = fn => (...args) => fn(...args).catch(args[args.length - 1]); // 带超时的异步操作 const withTimeout = (promise, timeout) => Promise.race([ promise, new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), timeout) ) ]);3. 性能优化关键点
JavaScript性能优化需要关注执行效率和内存管理:
3.1 减少重绘与回流
// 批量DOM操作 const batchDOMUpdates = elements => { const fragment = document.createDocumentFragment(); elements.forEach(el => fragment.appendChild(el)); document.body.appendChild(fragment); }; // 使用requestAnimationFrame优化动画 const animate = () => { requestAnimationFrame(() => { // 动画逻辑 animate(); }); };3.2 内存管理技巧
// 避免内存泄漏 class EventManager { constructor() { this.handlers = new WeakMap(); } addListener(element, event, handler) { const wrappedHandler = e => handler(e); this.handlers.set(handler, wrappedHandler); element.addEventListener(event, wrappedHandler); } removeListener(element, event, handler) { const wrappedHandler = this.handlers.get(handler); if (wrappedHandler) { element.removeEventListener(event, wrappedHandler); this.handlers.delete(handler); } } } // 大数组处理优化 const processLargeArray = (array, chunkSize = 1000, callback) => { let index = 0; function processChunk() { const chunk = array.slice(index, index + chunkSize); callback(chunk); index += chunkSize; if (index < array.length) { setTimeout(processChunk, 0); } } processChunk(); };4. 实用工具函数集锦
这些经过实战检验的工具函数能提升开发效率:
4.1 数据类型处理
// 精确类型判断 const typeOf = obj => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); // 深度比较 const deepEqual = (a, b) => { if (a === b) return true; if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) return false; const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; return keysA.every(key => deepEqual(a[key], b[key])); };4.2 函数式编程工具
// 函数柯里化 const curry = (fn, arity = fn.length, ...args) => arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args); // 函数记忆化 const memoize = fn => { const cache = new Map(); return (...args) => { const key = JSON.stringify(args); if (cache.has(key)) return cache.get(key); const result = fn(...args); cache.set(key, result); return result; }; }; // 管道函数 const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);5. 浏览器API高效用法
现代浏览器API提供了强大功能,正确使用能实现复杂交互:
5.1 本地存储优化
// 带过期时间的localStorage const storage = { set(key, value, ttl = 3600) { const item = { value, expiry: Date.now() + ttl * 1000 }; localStorage.setItem(key, JSON.stringify(item)); }, get(key) { const itemStr = localStorage.getItem(key); if (!itemStr) return null; const item = JSON.parse(itemStr); if (Date.now() > item.expiry) { localStorage.removeItem(key); return null; } return item.value; } };5.2 性能监控
// 页面性能指标收集 const getPerformanceMetrics = () => { const timing = performance.timing; const metrics = {}; // DNS查询时间 metrics.dns = timing.domainLookupEnd - timing.domainLookupStart; // TCP连接时间 metrics.tcp = timing.connectEnd - timing.connectStart; // 白屏时间 metrics.firstPaint = timing.responseStart - timing.navigationStart; // DOM解析时间 metrics.domReady = timing.domComplete - timing.domLoading; // 页面加载完成时间 metrics.loadComplete = timing.loadEventEnd - timing.navigationStart; return metrics; }; // 长任务监控 const observer = new PerformanceObserver(list => { list.getEntries().forEach(entry => { if (entry.duration > 50) { console.warn('Long task detected:', entry); } }); }); observer.observe({ entryTypes: ['longtask'] });6. 模块化开发实践
现代JavaScript开发离不开模块化,这些技巧能提升代码组织能力:
6.1 动态导入优化
// 按需加载组件 const loadComponent = async (componentName) => { try { const module = await import(`./components/${componentName}.js`); return module.default; } catch (err) { console.error(`Failed to load component ${componentName}`, err); return null; } }; // 预加载关键资源 const preloadResources = () => { const resources = [ '/critical.css', '/main.js', '/hero-image.jpg' ]; resources.forEach(resource => { const link = document.createElement('link'); link.rel = 'preload'; link.href = resource; link.as = resource.endsWith('.css') ? 'style' : resource.endsWith('.js') ? 'script' : 'image'; document.head.appendChild(link); }); };6.2 Web Worker应用
// 主线程代码 const worker = new Worker('worker.js'); worker.onmessage = e => { console.log('Result from worker:', e.data); }; worker.postMessage({ type: 'CALCULATE', data: largeDataSet }); // worker.js self.onmessage = e => { if (e.data.type === 'CALCULATE') { const result = processData(e.data.data); self.postMessage(result); } }; function processData(data) { // 复杂计算逻辑 return data.map(item => ({ ...item, processed: true })); }7. 调试与错误处理
健壮的错误处理机制是高质量代码的保障:
7.1 错误捕获策略
// 全局错误处理 window.addEventListener('error', event => { const { message, filename, lineno, colno, error } = event; logError({ type: 'UNCAUGHT_ERROR', message, stack: error?.stack, location: `${filename}:${lineno}:${colno}` }); // 可以阻止错误继续传播 // event.preventDefault(); }); // Promise未捕获错误 window.addEventListener('unhandledrejection', event => { const { reason } = event; logError({ type: 'UNHANDLED_REJECTION', message: reason?.message || String(reason), stack: reason?.stack }); }); // 错误上报函数 const logError = errorData => { navigator.sendBeacon('/error-log', JSON.stringify({ timestamp: Date.now(), ...errorData, userAgent: navigator.userAgent, url: location.href })); };7.2 调试技巧
// 条件调试 const debug = (condition, ...args) => { if (condition) { console.log('[DEBUG]', ...args); } }; // 性能调试 const measure = (fn, label = 'default') => { console.time(label); const result = fn(); console.timeEnd(label); return result; }; // DOM变化观察 const observeDOM = (target, callback) => { const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { callback(mutation); }); }); observer.observe(target, { attributes: true, childList: true, subtree: true, characterData: true }); return observer; };8. 现代JavaScript特性应用
ECMAScript新特性能显著提升代码质量和开发体验:
8.1 可选链与空值合并
// 安全访问嵌套属性 const getUserName = user => { return user?.profile?.name ?? 'Anonymous'; }; // 函数调用保护 const safeCall = fn => { try { return fn?.() ?? null; } catch { return null; } };8.2 私有类成员
class Counter { #value = 0; // 私有字段 get value() { return this.#value; } increment() { this.#value++; } reset() { this.#value = 0; } } // 使用WeakMap实现更早版本的私有成员 const privateData = new WeakMap(); class LegacyPrivateExample { constructor() { privateData.set(this, { secret: 42 }); } getSecret() { return privateData.get(this).secret; } }9. 安全编码实践
JavaScript安全是Web应用的重要保障:
9.1 XSS防护
// HTML转义 const escapeHTML = str => str.replace(/[&<>'"]/g, tag => ({ '&': '&', '<': '<', '>': '>', "'": ''', '"': '"' }[tag])); // 安全插入HTML const safeInsert = (element, content) => { if (content instanceof HTMLElement) { element.appendChild(content); } else { element.textContent = content; } }; // CSP兼容检查 const supportsCSP = () => { try { new Function('return 1;'); return false; } catch { return true; } };9.2 CSRF防护
// 自动添加CSRF令牌 const fetchWithCSRF = async (url, options = {}) => { const csrfToken = document.cookie.replace( /(?:(?:^|.*;\s*)XSRF-TOKEN\s*=\s*([^;]*).*$)|^.*$/, '$1' ); const headers = new Headers(options.headers || {}); headers.set('X-XSRF-TOKEN', csrfToken); return fetch(url, { ...options, headers, credentials: 'same-origin' }); };10. 实用代码片段
这些代码片段可以直接集成到项目中:
10.1 日期处理
// 日期格式化 const formatDate = (date, format = 'YYYY-MM-DD') => { const d = new Date(date); const pad = num => String(num).padStart(2, '0'); return format .replace(/YYYY/g, d.getFullYear()) .replace(/MM/g, pad(d.getMonth() + 1)) .replace(/DD/g, pad(d.getDate())) .replace(/HH/g, pad(d.getHours())) .replace(/mm/g, pad(d.getMinutes())) .replace(/ss/g, pad(d.getSeconds())); }; // 相对时间显示 const timeAgo = date => { const seconds = Math.floor((new Date() - new Date(date)) / 1000); const intervals = { year: 31536000, month: 2592000, week: 604800, day: 86400, hour: 3600, minute: 60 }; for (const [unit, secondsInUnit] of Object.entries(intervals)) { const interval = Math.floor(seconds / secondsInUnit); if (interval >= 1) { return `${interval} ${unit}${interval === 1 ? '' : 's'} ago`; } } return 'just now'; };10.2 字符串处理
// 生成随机ID const generateId = (length = 8) => { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0; i < length; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; }; // 驼峰转换 const toCamelCase = str => str.replace(/[-_](.)/g, (_, c) => c.toUpperCase()); // 首字母大写 const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1);11. 性能敏感场景优化
对于性能关键路径,这些优化技巧能带来显著提升:
11.1 高频事件处理
// 防抖函数 const debounce = (fn, delay = 300) => { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), delay); }; }; // 节流函数(时间戳+定时器版) const throttle = (fn, delay = 300) => { let timer = null; let lastTime = 0; return (...args) => { const now = Date.now(); const remaining = delay - (now - lastTime); if (remaining <= 0) { if (timer) { clearTimeout(timer); timer = null; } lastTime = now; fn(...args); } else if (!timer) { timer = setTimeout(() => { lastTime = Date.now(); timer = null; fn(...args); }, remaining); } }; };11.2 大数据量渲染
// 虚拟滚动实现 class VirtualScroll { constructor(container, itemHeight, totalItems, renderItem) { this.container = container; this.itemHeight = itemHeight; this.totalItems = totalItems; this.renderItem = renderItem; this.visibleCount = Math.ceil(container.clientHeight / itemHeight); this.startIndex = 0; this.endIndex = this.startIndex + this.visibleCount; this.content = document.createElement('div'); this.content.style.height = `${totalItems * itemHeight}px`; this.content.style.position = 'relative'; container.appendChild(this.content); this.render(); container.addEventListener('scroll', this.handleScroll.bind(this)); } handleScroll() { const scrollTop = this.container.scrollTop; this.startIndex = Math.floor(scrollTop / this.itemHeight); this.endIndex = Math.min( this.startIndex + this.visibleCount, this.totalItems ); this.render(); } render() { // 复用现有DOM元素 const fragment = document.createDocumentFragment(); for (let i = this.startIndex; i < this.endIndex; i++) { const item = document.createElement('div'); item.style.position = 'absolute'; item.style.top = `${i * this.itemHeight}px`; item.style.height = `${this.itemHeight}px`; item.style.width = '100%'; this.renderItem(item, i); fragment.appendChild(item); } this.content.innerHTML = ''; this.content.appendChild(fragment); } }12. 测试与质量保障
编写可测试的代码是长期维护的关键:
12.1 可测试代码模式
// 纯函数示例 const calculateDiscount = (price, discountRate) => { if (typeof price !== 'number' || price < 0) throw new Error('Invalid price'); if (typeof discountRate !== 'number' || discountRate < 0 || discountRate > 1) throw new Error('Invalid discount rate'); return price * (1 - discountRate); }; // 依赖注入示例 class UserService { constructor(userRepository) { this.userRepository = userRepository; } async getUser(id) { return this.userRepository.findById(id); } async createUser(userData) { // 验证逻辑 return this.userRepository.save(userData); } }12.2 测试工具函数
// 测试异步代码 const testAsync = (description, asyncFn) => { test(description, async () => { try { await asyncFn(); } catch (err) { // 增强错误信息 err.message = `[${description}] failed: ${err.message}`; throw err; } }); }; // 生成测试数据 const generateTestData = (schema, count = 1) => { const result = []; for (let i = 0; i < count; i++) { const item = {}; for (const [key, generator] of Object.entries(schema)) { item[key] = generator(i); } result.push(item); } return count === 1 ? result[0] : result; };13. 工程化实践
现代JavaScript项目需要良好的工程化支持:
13.1 配置管理
// 环境敏感配置 const config = { // 默认配置 api: { baseUrl: '/api', timeout: 30000 }, // 开发环境覆盖 ...(process.env.NODE_ENV === 'development' && { api: { baseUrl: 'http://localhost:3000/api' } }), // 测试环境覆盖 ...(process.env.NODE_ENV === 'test' && { api: { baseUrl: 'http://test.example.com/api' } }) }; // 配置验证 const validateConfig = config => { const requiredKeys = ['api.baseUrl', 'api.timeout']; const missingKeys = requiredKeys.filter(key => { const parts = key.split('.'); let current = config; for (const part of parts) { if (!current[part]) return true; current = current[part]; } return false; }); if (missingKeys.length) { throw new Error(`Missing required config keys: ${missingKeys.join(', ')}`); } };13.2 构建优化
// 动态加载polyfill const loadPolyfills = async () => { const polyfills = []; if (!window.Promise) { polyfills.push(import('promise-polyfill')); } if (!window.fetch) { polyfills.push(import('whatwg-fetch')); } if (!Object.entries) { polyfills.push(import('object.entries')); } await Promise.all(polyfills); }; // 代码分割策略 const lazyLoadComponent = async (componentName) => { try { const module = await import( /* webpackChunkName: "[request]" */ `./components/${componentName}` ); return module.default; } catch (err) { console.error('Failed to load component', err); // 回退到默认组件 const module = await import('./components/Fallback'); return module.default; } };14. 跨平台开发技巧
JavaScript不仅限于浏览器环境,这些技巧适用于多平台:
14.1 Node.js特定优化
// 环境变量处理 const getEnv = (key, defaultValue = null) => { const value = process.env[key]; if (value === undefined) { if (defaultValue === null) { throw new Error(`Missing required environment variable: ${key}`); } return defaultValue; } return value; }; // 命令行参数解析 const parseArgs = () => { const args = {}; process.argv.slice(2).forEach(arg => { const [key, value] = arg.split('='); args[key.replace(/^-+/, '')] = value || true; }); return args; }; // 性能监控 const monitorPerformance = () => { const startUsage = process.cpuUsage(); const startMemory = process.memoryUsage(); return { getMetrics() { const cpuUsage = process.cpuUsage(startUsage); const memoryUsage = process.memoryUsage(); return { cpuUser: cpuUsage.user / 1000, // ms cpuSystem: cpuUsage.system / 1000, // ms memoryRss: (memoryUsage.rss - startMemory.rss) / 1024 / 1024, // MB heapUsed: (memoryUsage.heapUsed - startMemory.heapUsed) / 1024 / 1024, // MB heapTotal: (memoryUsage.heapTotal - startMemory.heapTotal) / 1024 / 1024 // MB }; } }; };14.2 同构应用技巧
// 环境判断 const isServer = typeof window === 'undefined'; // 通用数据获取 const fetchData = async (url) => { if (isServer) { const { default: fetch } = await import('node-fetch'); return fetch(url).then(res => res.json()); } return window.fetch(url).then(res => res.json()); }; // 同构渲染 class UniversalComponent { constructor(data) { this.data = data; } render() { if (isServer) { return this.renderToString(); } return this.renderToDOM(); } renderToString() { return `<div>${this.data}</div>`; } renderToDOM() { const div = document.createElement('div'); div.textContent = this.data; return div; } }15. 前沿技术探索
JavaScript生态不断发展,这些新兴技术值得关注:
15.1 WebAssembly集成
// 加载WebAssembly模块 const loadWasm = async (url, imports = {}) => { const response = await fetch(url); const buffer = await response.arrayBuffer(); const module = await WebAssembly.compile(buffer); const instance = await WebAssembly.instantiate(module, imports); return instance.exports; }; // 与JavaScript交互 const runWasmAlgorithm = async () => { const wasm = await loadWasm('algorithm.wasm'); // 准备输入数据 const input = new Float64Array([1, 2, 3, 4, 5]); const inputPointer = wasm.allocate(input.length * Float64Array.BYTES_PER_ELEMENT); new Float64Array(wasm.memory.buffer, inputPointer, input.length).set(input); // 调用Wasm函数 const outputPointer = wasm.process_data(inputPointer, input.length); // 获取结果 const output = new Float64Array( wasm.memory.buffer, outputPointer, input.length ); // 释放内存 wasm.deallocate(inputPointer); wasm.deallocate(outputPointer); return Array.from(output); };15.2 Web Components应用
// 自定义元素定义 class MyElement extends HTMLElement { static get observedAttributes() { return ['disabled', 'size']; } constructor() { super(); this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = ` <style> :host { display: inline-block; } :host([disabled]) { opacity: 0.5; pointer-events: none; } </style> <slot></slot> `; } connectedCallback() { console.log('Element added to DOM'); } disconnectedCallback() { console.log('Element removed from DOM'); } attributeChangedCallback(name, oldValue, newValue) { console.log(`Attribute ${name} changed from ${oldValue} to ${newValue}`); } } // 注册自定义元素 customElements.define('my-element', MyElement); // 使用动态导入加载自定义元素 const loadCustomElement = async (tagName, elementPath) => { if (!customElements.get(tagName)) { const module = await import(elementPath); customElements.define(tagName, module.default); } };16. 代码风格与规范
一致的代码风格有助于团队协作和长期维护:
16.1 代码格式化规则
// ESLint配置示例 module.exports = { env: { browser: true, es2021: true }, extends: [ 'eslint:recommended', 'plugin:prettier/recommended' ], parserOptions: { ecmaVersion: 12, sourceType: 'module' }, rules: { 'no-console': 'warn', 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], 'prefer-const': 'error', 'arrow-body-style': ['error', 'as-needed'], 'object-shorthand': ['error', 'always'], 'prettier/prettier': ['error', { printWidth: 100, tabWidth: 2, useTabs: false, semi: true, singleQuote: true, trailingComma: 'es5', bracketSpacing: true, arrowParens: 'avoid' }] } }; // Prettier忽略配置 { "ignoreFiles": [ "**/*.min.js", "dist/**", "node_modules/**", "coverage/**", "**/vendor/*.js" ] }16.2 代码组织模式
// 模块导出最佳实践 // 优先使用命名导出 export const CONSTANT_VALUE = 42; export function utilityFunction() { // ... } export class MainClass { // ... } // 默认导出应该用于主要功能 export default function mainFunction() { // ... } // 或者导出整个模块的主要功能 export { default } from './MainComponent'; // 索引文件组织 // src/components/index.js export { default as Button } from './Button'; export { default as Input } from './Input'; export { default as Modal } from './Modal'; // 按功能组织的目录结构 /* src/ features/ user/ components/ hooks/ services/ utils/ index.js product/ components/ hooks/ services/ utils/ index.js */17. 调试与性能分析
深入掌握调试工具能极大提升开发效率:
17.1 Chrome DevTools高级用法
// 条件断点 function processItems(items) { for (const item of items) { // 右键点击行号 -> Add conditional breakpoint // 输入条件如: item.id === 'special' console.log('Processing item:', item); } } // 日志点 function calculateTotal(items) { // 右键点击行号 -> Add logpoint // 输入表达式如: 'Calculating total for', items.length, 'items' return items.reduce((total, item) => total + item.price, 0); } // 性能分析标记 function performComplexCalculation() { performance.mark('calc-start'); // 复杂计算... performance.mark('calc-end'); performance.measure('calculation', 'calc-start', 'calc-end'); } // 内存快照分析 function analyzeMemory() { // 在DevTools Memory面板手动操作 const largeData = new Array(1000000).fill({}); // 执行某些操作后... return processData(largeData); }17.2 Node.js调试技巧
// 调试器语句 function debugFunction() { debugger; // 执行会在此暂停 // ... } // 性能分析 const { performance, PerformanceObserver } = require('perf_hooks'); const obs = new PerformanceObserver(items => { console.log(items.getEntries()[0].duration); performance.clearMarks(); }); obs.observe({ entryTypes: ['measure'] }); performance.mark('start'); // 要测量的代码 performance.mark('end'); performance.measure('My Operation', 'start', 'end'); // 内存泄漏检测 const heapdump = require('heapdump'); function checkMemory() { if (process.memoryUsage().heapUsed > 500 * 1024 * 1024) { heapdump.writeSnapshot(`heapdump-${Date.now()}.heapsnapshot`); } } setInterval(checkMemory, 10000);18. 代码重构模式
定期重构是保持代码健康的关键:
18.1 常见重构技巧
// 提取函数 function processOrder(order) { // 重构前 if (order.items.length > 0) { let total = 0; for (const item of order.items) { total += item.price * item.quantity; } if (order.customer.isVIP) { total *= 0.9; } order.total = total; } // 重构后 if (order.items.length > 0) { order.total = calculateOrderTotal(order); } } function calculateOrderTotal(order) { const subtotal = order.items.reduce( (sum, item) => sum + item.price * item.quantity, 0 ); return applyDiscount(subtotal, order.customer); } function applyDiscount(amount, customer) { return customer.isVIP ? amount * 0.9 : amount; } // 替换条件表达式 // 重构前 function getSpeed(type) { switch (type) { case 'car': return 100; case 'truck': return 60; case 'plane': return 500; default: return 0; } } // 重构后 const speedMap = { car: 100, truck: 60, plane: 500 }; function getSpeed(type) { return speedMap[type] || 0; }18.2 异步代码重构
// 回调转Promise // 重构前 function fetchData(callback) { fs.readFile('data.json', 'utf8', (err, data) => { if (err) return callback(err); try { const parsed = JSON.parse(data); callback(null, parsed); } catch (e) { callback(e); } }); } // 重构后 function fetchData() { return new Promise((resolve, reject) => { fs.readFile('data.json', 'utf8', (err, data) => { if (err) return reject(err); try { resolve(JSON.parse(data)); } catch (e) { reject(e); } }); }); } // 更进一步的现代写法 const { promises: fs } = require('fs'); async function fetchData() { const data = await fs.readFile('data.json', 'utf8'); return JSON.parse(data); } // Promise链优化 // 重构前 function processUser(userId) { return fetchUser(userId) .then(user => { return fetchProfile(user.profileId) .then(profile => { return { ...user, profile }; }); }) .then(userWithProfile => { return fetchOrders(userWithProfile.id) .then(orders => { return { ...userWithProfile, orders }; }); }); } // 重构后 async function processUser(userId) { const user = await fetchUser(userId); const [profile, orders] = await Promise.all([ fetchProfile(user.profileId), fetchOrders(user.id) ]); return { ...user, profile, orders }; }19. 设计模式应用
JavaScript中常用设计