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

JavaScript系列(18)--异步编程模式

JavaScript异步编程模式 🔄

今天,让我们深入探讨JavaScript中的异步编程模式。异步编程是JavaScript中非常重要的概念,它帮助我们处理非阻塞操作和提高应用性能。

异步编程基础 🌟

💡 小知识:JavaScript是单线程的,但通过事件循环和异步编程模式,我们可以实现非阻塞的操作,从而提高应用的响应性和性能。

回调函数模式 📊

// 1. 基本回调模式
function callbackPatterns() {
    // 简单回调
    function fetchData(callback) {
        setTimeout(() => {
            const data = { id: 1, name: 'Example' };
            callback(null, data);
        }, 1000);
    }
    
    // 错误优先回调
    fetchData((error, data) => {
        if (error) {
            console.error('Error:', error);
            return;
        }
        console.log('Data:', data);
    });
    
    // 嵌套回调(回调地狱)
    fetchData((error1, data1) => {
        if (error1) return console.error(error1);
        
        fetchData((error2, data2) => {
            if (error2) return console.error(error2);
            
            fetchData((error3, data3) => {
                if (error3) return console.error(error3);
                
                console.log('All data:', data1, data2, data3);
            });
        });
    });
}

// 2. 回调函数改进
class CallbackManager {
    // 串行执行回调
    static series(tasks, finalCallback) {
        const results = [];
        let completed = 0;
        
        function next() {
            if (completed >= tasks.length) {
                finalCallback(null, results);
                return;
            }
            
            tasks[completed]((error, result) => {
                if (error) {
                    finalCallback(error);
                    return;
                }
                
                results.push(result);
                completed++;
                next();
            });
        }
        
        next();
    }
    
    // 并行执行回调
    static parallel(tasks, finalCallback) {
        const results = new Array(tasks.length);
        let completed = 0;
        let hasError = false;
        
        tasks.forEach((task, index) => {
            task((error, result) => {
                if (hasError) return;
                
                if (error) {
                    hasError = true;
                    finalCallback(error);
                    return;
                }
                
                results[index] = result;
                completed++;
                
                if (completed === tasks.length) {
                    finalCallback(null, results);
                }
            });
        });
    }
}

// 3. 事件发射器模式
class EventEmitter {
    constructor() {
        this.events = new Map();
    }
    
    on(event, callback) {
        if (!this.events.has(event)) {
            this.events.set(event, []);
        }
        this.events.get(event).push(callback);
        
        return () => this.off(event, callback);
    }
    
    off(event, callback) {
        const callbacks = this.events.get(event);
        if (callbacks) {
            const index = callbacks.indexOf(callback);
            if (index !== -1) {
                callbacks.splice(index, 1);
            }
        }
    }
    
    emit(event, ...args) {
        const callbacks = this.events.get(event);
        if (callbacks) {
            callbacks.forEach(callback => callback(...args));
        }
    }
    
    once(event, callback) {
        const wrapper = (...args) => {
            callback(...args);
            this.off(event, wrapper);
        };
        return this.on(event, wrapper);
    }
}

Promise模式 🔄

// 1. Promise基础操作
class PromisePatterns {
    // 创建Promise
    static createPromise() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                const random = Math.random();
                if (random > 0.5) {
                    resolve('Success!');
                } else {
                    reject(new Error('Failed!'));
                }
            }, 1000);
        });
    }
    
    // Promise链式调用
    static chainPromises() {
        return this.createPromise()
            .then(result => {
                console.log('First then:', result);
                return 'Next value';
            })
            .then(result => {
                console.log('Second then:', result);
                throw new Error('Custom error');
            })
            .catch(error => {
                console.error('Caught error:', error);
                return 'Recovered';
            })
            .finally(() => {
                console.log('Finally block executed');
            });
    }
    
    // Promise并行执行
    static parallel() {
        const promises = [
            this.createPromise(),
            this.createPromise(),
            this.createPromise()
        ];
        
        return Promise.all(promises)
            .then(results => {
                console.log('All succeeded:', results);
            })
            .catch(error => {
                console.error('One failed:', error);
            });
    }
}

// 2. Promise工具函数
class PromiseUtils {
    // 超时包装
    static timeout(promise, ms) {
        const timeoutPromise = new Promise((_, reject) => {
            setTimeout(() => reject(new Error('Timeout')), ms);
        });
        
        return Promise.race([promise, timeoutPromise]);
    }
    
    // 重试机制
    static retry(fn, retries = 3, delay = 1000) {
        return new Promise((resolve, reject) => {
            function attempt() {
                fn().then(resolve).catch(error => {
                    if (retries === 0) {
                        reject(error);
                        return;
                    }
                    
                    retries--;
                    setTimeout(attempt, delay);
                });
            }
            
            attempt();
        });
    }
    
    // 串行执行Promise
    static series(tasks) {
        return tasks.reduce(
            (promise, task) => promise.then(results => 
                task().then(result => [...results, result])
            ),
            Promise.resolve([])
        );
    }
}

// 3. Promise池
class PromisePool {
    constructor(maxConcurrent) {
        this.maxConcurrent = maxConcurrent;
        this.running = 0;
        this.queue = [];
    }
    
    add(promiseFactory) {
        return new Promise((resolve, reject) => {
            this.queue.push({ promiseFactory, resolve, reject });
            this.run();
        });
    }
    
    run() {
        while (this.running < this.maxConcurrent && this.queue.length > 0) {
            const { promiseFactory, resolve, reject } = this.queue.shift();
            this.running++;
            
            promiseFactory()
                .then(resolve)
                .catch(reject)
                .finally(() => {
                    this.running--;
                    this.run();
                });
        }
    }
}

Async/Await模式 🔄

// 1. 基本使用
class AsyncAwaitPatterns {
    // 异步函数
    static async fetchData() {
        try {
            const response = await fetch('https://api.example.com/data');
            const data = await response.json();
            return data;
        } catch (error) {
            console.error('Error fetching data:', error);
            throw error;
        }
    }
    
    // 并行执行
    static async parallel() {
        try {
            const [result1, result2] = await Promise.all([
                this.fetchData(),
                this.fetchData()
            ]);
            
            return { result1, result2 };
        } catch (error) {
            console.error('Error in parallel execution:', error);
            throw error;
        }
    }
    
    // 串行执行
    static async series() {
        try {
            const result1 = await this.fetchData();
            const result2 = await this.fetchData();
            
            return { result1, result2 };
        } catch (error) {
            console.error('Error in series execution:', error);
            throw error;
        }
    }
}

// 2. 异步迭代器
class AsyncIteratorPatterns {
    // 异步生成器
    static async *generateData() {
        for (let i = 0; i < 5; i++) {
            await new Promise(resolve => setTimeout(resolve, 1000));
            yield i;
        }
    }
    
    // 使用for-await-of
    static async consumeData() {
        for await (const value of this.generateData()) {
            console.log('Generated value:', value);
        }
    }
    
    // 自定义异步迭代器
    static createAsyncIterator(array) {
        let index = 0;
        
        return {
            async next() {
                if (index < array.length) {
                    await new Promise(resolve => setTimeout(resolve, 1000));
                    return { value: array[index++], done: false };
                }
                return { done: true };
            },
            [Symbol.asyncIterator]() {
                return this;
            }
        };
    }
}

// 3. 异步工具函数
class AsyncUtils {
    // 异步重试
    static async retry(fn, options = {}) {
        const {
            retries = 3,
            delay = 1000,
            onRetry = null
        } = options;
        
        let lastError;
        
        for (let i = 0; i < retries; i++) {
            try {
                return await fn();
            } catch (error) {
                lastError = error;
                if (onRetry) {
                    onRetry(error, i + 1);
                }
                if (i < retries - 1) {
                    await new Promise(resolve => setTimeout(resolve, delay));
                }
            }
        }
        
        throw lastError;
    }
    
    // 异步超时
    static async timeout(promise, ms) {
        let timeoutId;
        
        const timeoutPromise = new Promise((_, reject) => {
            timeoutId = setTimeout(() => {
                reject(new Error(`Operation timed out after ${ms}ms`));
            }, ms);
        });
        
        try {
            const result = await Promise.race([promise, timeoutPromise]);
            clearTimeout(timeoutId);
            return result;
        } catch (error) {
            clearTimeout(timeoutId);
            throw error;
        }
    }
    
    // 异步批处理
    static async batch(items, batchSize, processor) {
        const results = [];
        
        for (let i = 0; i < items.length; i += batchSize) {
            const batch = items.slice(i, i + batchSize);
            const batchResults = await Promise.all(
                batch.map(item => processor(item))
            );
            results.push(...batchResults);
        }
        
        return results;
    }
}

性能优化 ⚡

异步编程中的性能优化技巧:

// 1. 并发控制
class ConcurrencyControl {
    constructor(maxConcurrent = 5) {
        this.maxConcurrent = maxConcurrent;
        this.running = 0;
        this.queue = [];
    }
    
    async add(task) {
        if (this.running >= this.maxConcurrent) {
            await new Promise(resolve => this.queue.push(resolve));
        }
        
        this.running++;
        
        try {
            return await task();
        } finally {
            this.running--;
            if (this.queue.length > 0) {
                const next = this.queue.shift();
                next();
            }
        }
    }
}

// 2. 缓存优化
class AsyncCache {
    constructor() {
        this.cache = new Map();
        this.pending = new Map();
    }
    
    async get(key, fetcher) {
        // 检查缓存
        if (this.cache.has(key)) {
            return this.cache.get(key);
        }
        
        // 检查是否有pending请求
        if (this.pending.has(key)) {
            return this.pending.get(key);
        }
        
        // 创建新请求
        const promise = fetcher().then(result => {
            this.cache.set(key, result);
            this.pending.delete(key);
            return result;
        });
        
        this.pending.set(key, promise);
        return promise;
    }
    
    invalidate(key) {
        this.cache.delete(key);
        this.pending.delete(key);
    }
}

// 3. 资源池化
class ResourcePool {
    constructor(factory, options = {}) {
        this.factory = factory;
        this.resources = [];
        this.maxSize = options.maxSize || 10;
        this.minSize = options.minSize || 2;
        this.createInitialResources();
    }
    
    async createInitialResources() {
        for (let i = 0; i < this.minSize; i++) {
            const resource = await this.factory();
            this.resources.push(resource);
        }
    }
    
    async acquire() {
        if (this.resources.length > 0) {
            return this.resources.pop();
        }
        
        if (this.resources.length < this.maxSize) {
            return await this.factory();
        }
        
        return new Promise(resolve => {
            this.waitQueue.push(resolve);
        });
    }
    
    async release(resource) {
        if (this.waitQueue.length > 0) {
            const resolve = this.waitQueue.shift();
            resolve(resource);
        } else if (this.resources.length < this.maxSize) {
            this.resources.push(resource);
        }
    }
}

最佳实践建议 💡

  1. 错误处理
// 1. 全局错误处理
class AsyncErrorHandler {
    static handleAsyncErrors(fn) {
        return async (...args) => {
            try {
                return await fn(...args);
            } catch (error) {
                console.error('Async error:', error);
                this.reportError(error);
                throw error;
            }
        };
    }
    
    static reportError(error) {
        // 实现错误报告逻辑
    }
}

// 2. 优雅降级
class GracefulDegradation {
    static async withFallback(primaryFn, fallbackFn) {
        try {
            return await primaryFn();
        } catch (error) {
            console.warn('Primary function failed, using fallback:', error);
            return fallbackFn();
        }
    }
}

// 3. 重试策略
class RetryStrategy {
    static async withBackoff(fn, maxRetries = 3) {
        let retryCount = 0;
        
        while (true) {
            try {
                return await fn();
            } catch (error) {
                retryCount++;
                if (retryCount >= maxRetries) {
                    throw error;
                }
                
                const delay = Math.pow(2, retryCount) * 1000;
                await new Promise(resolve => setTimeout(resolve, delay));
            }
        }
    }
}

结语 📝

异步编程是JavaScript中非常重要的概念,掌握各种异步模式可以帮助我们写出更高效、更可维护的代码。我们学习了:

  1. 回调函数模式及其改进
  2. Promise的使用和工具函数
  3. Async/Await的最佳实践
  4. 性能优化技巧
  5. 错误处理策略

💡 学习建议:从简单的回调开始,逐步掌握Promise和Async/Await。注意错误处理和性能优化,选择合适的模式来处理不同的异步场景。


如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻


http://www.kler.cn/a/488420.html

相关文章:

  • vue 导出excel接口请求和axios返回值blob类型处理
  • <rust>在rust中,实现32位浮点数与16进制之间的转换
  • 如何在 Ubuntu 22.04 上安装 Nagios 服务器教程
  • C++ 如何将 gRPC集成到机器人系统中
  • “深入浅出”系列之QT:(6)如何在一个项目中调用另一个项目
  • 【C++/控制台】2048小游戏
  • 【UI自动化测试】selenium操作补充
  • 【Docker】docker compose 安装 Redis Stack
  • Linux 文件的特殊权限—ACL权限控制
  • JavaScript Chrome 中的运行
  • Android 12.0 mtk平板camera2横屏预览旋转90度横屏保存录像旋转90度功能实现
  • Python对象的序列化和反序列化工具:Joblib与Pickle
  • Linux 系统 PWM 风扇驱动框架学习记录
  • 【比较乱,如果遇到相同问题可以看】Autoware.universe的绕障线路的参数修改
  • CSS——39. 文本修饰(文本属性)
  • 用 Python 绘制可爱的招财猫
  • 新车月交付突破2万辆!小鹏汽车“激活”智驾之困待解
  • Uniapp仿ChatGPT Stream流式输出(非Websocket)
  • UML(统一建模语言)
  • VUE3 VITE项目在 npm 中,关于 Vue 的常用命令有一些基础命令
  • clickhouse 离线包安装(ubuntu)
  • SOLIDWORKS 或 AutoCAD:选择CAD 解决方案时应考虑哪些问题?
  • TR-069协议学习--Soap报文、事件、RPC方法
  • ubuntu报错:没有在该文件夹中粘贴文件的权限
  • 【Unity功能集】TextureShop纹理工坊(十二)画笔工具、橡皮擦工具
  • 初学stm32 --- DAC输出