前端技巧第七期JavaScript异步

异步核心概念

优点
避免阻塞:JavaScript是单线程语言,异步操作可防止长时间任务阻塞主线程
提升性能:充分利用I/O等待时间处理其他任务
响应式体验:保持UI流畅响应,特别是在浏览器环境中
事件循环机制
// 演示事件循环执行顺序
console.log('Start');
setTimeout(() => console.log('Timeout'), 0);
Promise.resolve().then(() => console.log('Promise'));
console.log('End');
/* 输出顺序:
Start
End
Promise
Timeout
*/
执行上下文
调用栈(Call Stack):同步代码执行容器
任务队列(Task Queue):存放宏任务(setTimeout、I/O)
微任务队列(Microtask Queue):存放微任务(Promise、MutationObserver)

异步编程演进史

回调函数(Callback)
 function fetchData(callback) {
    setTimeout(() => {
       callback('Data received');
   }, 1000);
}
fetchData((data) => {
            // 1秒后输出
            console.log(data);
});
回调函数存在的问题:回调地狱(Callback Hell)
getUser(userId, (user) => {
    getOrders(user.id, (orders) => {
         getProducts(orders[0].id, (products) => {
            renderPage(user, orders, products);
         });
    });
});
Promise(ES6)
        const promiseExample = new Promise((resolve, reject) => {
            setTimeout(() => {
                Math.random() > 0.5 ? resolve('Success!') : reject(new Error('Failed'));
            }, 1000);
        });
        promiseExample
            .then(console.log)
            .catch(console.error);
async/await(ES2017)
        async function fetchUser() {
            try {
                const response = await fetch('/api/user');
                const data = await response.json();
                return data;
            } catch (error) {
                console.error('Fetch failed:', error);
            }
        }

Promise 深度解析

状态管理
Pending(进行中)  
Fulfilled(已成功)  
Rejected(已失败)
链式调用
        checkInventory()
            .then((stock) => placeOrder(stock))
            .then((order) => processPayment(order))
            .then((receipt) => sendConfirmation(receipt))
            .catch(handleErrors);
组合方法
  		// 并行执行
        Promise.all([api1, api2, api3])
            .then(([res1, res2, res3]) => {/* ... */ });
        // 竞速模式
        Promise.race([fastAPI, slowAPI])
        .then(firstResult => { /* ... */ });
        // 全成功或全部失败
        Promise.allSettled([req1, req2])
        .then(results => { /* ... */ });

async/await最佳实践

错误处理模式
        // 方法1:try/catch
        async function safeFetch() {
            try {
                const res = await fetch(url);
                return await res.json();
            } catch (err) {
                console.error('Request failed:', err);
                return null;
            }
        }
        // 方法2:高阶函数封装
        const asyncHandler = (promise) =>
            promise.then(data => [null, data])
                .catch(err => [err, null]);
并行优化
        // 顺序执行(低效)
        const user = await getUser();
        const orders = await getOrders(user.id);
        // 并行执行(推荐)
        const [user, orders] = await Promise.all([
            getUser(),
            getOrders(userId)
        ]);
循环中的异步
        // 错误方式(forEach不等待)
        array.forEach(async item => {
            await process(item);
        });
        // 正确方式
        for (const item of array) {
            await process(item); // 顺序执行
        }
        // 并行方式
        await Promise.all(array.map(item => process(item)));

高级异步模式

发布订阅模式
        class EventEmitter {
            constructor() {
                this.events = {};
            }
            on(event, listener) {
                (this.events[event] || (this.events[event] = [])).push(listener);
            }
            emit(event, ...args) {
                (this.events[event] || []).forEach(listener => listener(...args));
            }
        }
Web Workers
        // main.js
        const worker = new Worker('worker.js');
        worker.postMessage({
            type: 'CALC', data: bigArray
        });
        worker.onmessage = (e) => {
            console.log('Result:', e.data);
        };
        // worker.js
        self.onmessage = function (e) {
            if (e.data.type === 'CALC') {
                const result = heavyCalculation(e.data.data);
                self.postMessage(result);
            }
        };

错误处理策略

全局错误捕获
		// 浏览器环境
        window.addEventListener('unhandledrejection', (event) => {
            console.error('Unhandled rejection:', event.reason);
        });
        // Node.js环境
        process.on('unhandledRejection', (reason, promise) => {
            console.error('Unhandled Rejection at:', promise, 'reason:', reason);
        });
重试机制
        async function retry(fn, retries = 3, delay = 1000) {
            try {
                return await fn();
            } catch (err) {
                if (retries <= 0) throw err;
                await new Promise(res => setTimeout(res, delay));
                return retry(fn, retries - 1, delay * 2);
            }
        }

性能优化

节流防抖
        // 防抖实现
        function debounce(fn, delay) {
            let timer;
            return (...args) => {
                clearTimeout(timer);
                timer = setTimeout(() => fn(...args), delay);
            };
        }
        // 节流实现
        function throttle(fn, interval) {
            let lastTime = 0;
            return (...args) => {
                const now = Date.now();
                if (now - lastTime >= interval) {
                    fn(...args); lastTime = now;
                }
            };
        }
请求缓存
        const apiCache = new Map();
        async function cachedFetch(url) {
            if (apiCache.has(url)) {
                return apiCache.get(url);
            }
            const response = await fetch(url);
            const data = await response.json();
            apiCache.set(url, data); return data;
        }

开发场景


        async function loadPageData() {
            const [user, posts] = await Promise.all([fetch('/api/user'), fetch('/api/posts')]);
            return { user: await user.json(), posts: await posts.json() };
        }

文件上传处理

        async function uploadFiles(files) {
            const uploadPromises = files.map(file => {
                const formData = new FormData(); formData.append('file', file);
                return fetch('/upload', { method: 'POST', body: formData });
            });
            const results = await Promise.allSettled(uploadPromises);  // 处理上传结果
        }

结语

 1.优先使用async/await:提升代码可读性    
 2.避免过度并行:控制并发数量(使用p-limit等库)    
 3.及时清理资源:取消不必要的请求(AbortController)    
 4.监控异步性能:使用Performance API进行分析    
 5.保持错误可追踪:附加上下文错误信息
        // 使用AbortController取消请求
        const controller = new AbortController();
        fetch(url, {
            signal: controller.signal
        }).then(/* ... */).catch(err => {
            if (err.name === 'AbortError') {
                console.log('Request aborted');
            }
        });
        // 取消请求
        controller.abort();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值