Promise的玩法

一、Promise基础概念

1.1 核心特性

Promise是ES6引入的异步编程解决方案,具有三大核心特性:

  • 状态不可逆性:仅能从pending→fulfilled或pending→rejected单向转换
  • 链式调用:通过then/catch串联异步操作
  • 统一错误处理:catch集中捕获链式调用中的异常

1.2 基本结构

js 复制代码
const fetchData = new Promise((resolve, reject) => {  
// 异步操作  
setTimeout(() => {     
resolve('操作成功'); // 成功状态
// reject(new Error('操作失败')); // 失败状态  
}, 1000);
});
fetchData.then(data => console.log(data)) // 成功回调  
.catch(err => console.error(err)); // 错误处理 

二、进阶应用场景

2.1 异步流程控制

串行请求(依赖前序结果)

js 复制代码
function getUser(id) {   return fetch(`/api/users/${id}`).then(res => res.json()); }  
function getPosts(userId) {   return fetch(`/api/posts/${userId}`).then(res => res.json()); }  // 自动等待前序请求完成
getUser(1).then(user => getPosts(user.id)).then(posts => console.log(posts)).catch(console.error); 

并行请求(Promise.all)

js 复制代码
Promise.all([   fetch('/api/users').then(res => res.json()),  
fetch('/api/posts').then(res => res.json()) ]).then(([users, posts]) => {  
console.log('用户数据:', users);  
console.log('帖子数据:', posts); 
}); 

2.2 错误处理机制

穿透式错误捕获

js 复制代码
fetchData.then(processData).then(saveData).catch(err => {     
console.error('流程中断:', err);     
return Promise.reject(err); // 保持错误传递  
}); 

2.3 状态管理进阶

手动状态控制(模拟加载状态)

js 复制代码
class DataLoader {  
constructor() {    
this.promise = new Promise((resolve, reject) => {      
this.resolve = resolve;       
this.reject = reject;});  
}      
load() {    
// 模拟异步加载     
setTimeout(() => {      
this.resolve(loadedData);}, 1000);   
}    
cancel() {     
this.reject(new Error('操作取消'));  
} } 

三、企业级实践方案

3.1 请求封装示例

js 复制代码
class APIClient { 
constructor(baseURL) {     this.baseURL = baseURL;   }     
request(options) {    
return new Promise((resolve, reject) => {    
const xhr = new XMLHttpRequest();       
xhr.open(options.method, `${this.baseURL}${options.path}`);           
xhr.onload = () => {        
if (xhr.status >= 200 && xhr.status < 300) {         
resolve(JSON.parse(xhr.response));         
} else {          
reject(new Error(`请求失败: ${xhr.status}`));         
}       };              
xhr.onerror = () => reject(new Error('网络错误'));      
xhr.send(options.data || null);});   
} }  
// 使用示例 
const client = new APIClient('https://api.example.com');
client.request({   method: 'GET',   path: '/users' }) .then(users => console.log(users)) .catch(console.error); 

3.2 性能优化策略

请求池化技术

js 复制代码
class RequestPool {   
constructor(maxConcurrent = 5) {    
this.queue = [];    
this.running = 0;     
this.max = maxConcurrent;   
}     
add(promise) {    
this.queue.push(promise);    
if (this.running < this.max) {       
this._runNext();     
}     
return promise;   }     
_runNext() {     
if (this.queue.length === 0) return;          
const task = this.queue.shift();     
task.finally(() => {       
this.running--;        
this._runNext();      
});     
this.running++;   } }  
// 使用示例 
const pool = new RequestPool(3); 
for (let i = 0; i < 8; i++) {   
pool.add(fetch(`/api/data/${i}`)); 
} 

四、常见问题解析

4.1 执行顺序陷阱

js 复制代码
console.log(1); 
new Promise(resolve => {   
console.log(2);   
setTimeout(() => {    
console.log('timer');    
resolve();   }, 0);   
console.log(3); }) .then(() => console.log(4)); 
console.log(5); // 输出顺序: 1 → 2 → 3 → 5 → timer → 4 
相关推荐
晨枫阳1 分钟前
Vue 前端构建工具链完全理解指南
前端·javascript·vue.js
言乐62 分钟前
Python关于老游复刻与创新2
前端·javascript·css·python·css3
ly76892 分钟前
前端测试完整指南:从单元测试、组件测试到端到端测试与 CI/CD
前端·ci/cd·单元测试
钛态9 小时前
Vite 中的 CSS 工程化:从 CSS Modules 到 UnoCSS 的渐进式迁移
前端·vue·react·web
Csvn10 小时前
原型链、this 与闭包内存:三座深水区一次打通(含内存泄漏排查实战)
前端·javascript
葡萄城技术团队11 小时前
如何通过 JSON 数据源 / Web API 快速构建轻量级报表(Report)?
前端·json·原型模式
浪兎兎11 小时前
【Java Web】Servlet + JSP 笔记
java·前端·servlet
Patrick_Wilson12 小时前
iOS Safari Clipboard API 权限弹窗问题
前端·ios·safari
OpenTiny社区12 小时前
Naive UI × GenUI SDK:自定义物料库搭建实战
前端·ai编程
kyriewen13 小时前
我拿 4 个真实前端任务试了 GLM-5.3 Flash:代码一遍跑通,账单 4 分钱
前端·程序员·ai编程