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 
相关推荐
WindrunnerMax5 小时前
在富文本编辑器中实现 Markdown 流式增量解析算法
前端·github·aigc
coding随想5 小时前
指尖的魔法:触摸事件(Touch Events)如何让网页在你掌心起舞?
前端
一只毛驴5 小时前
视频播放器的编解码
前端·javascript
Chaoran5 小时前
浏览器加载外部资源性能优化
前端·javascript·面试
子兮曰5 小时前
别再手动处理API数据了!这个BFF数据转换层让你的开发效率提升300%
前端·javascript·api
知识分享小能手5 小时前
React学习教程,从入门到精通, React 入门指南:创建 React 应用程序的语法知识点(7)
前端·javascript·vue.js·学习·react.js·前端框架·anti-design-vue
golang学习记5 小时前
从0死磕全栈第2天:Vite + React 配置全解析,让你的开发效率飞起来
前端
liusheng6 小时前
fly.js 对 DELETE 请求无法传入 body 的问题
前端·javascript
前端_小_小白6 小时前
前端程序员修炼手册:从像素仔到体验守护者
前端·javascript