2024/03/08 异步处理,解剖Promise
异步处理
异步处理是指在程序执行过程中,某些操作不会阻塞当前线程,而是通过回调函数、Promise、async/await 等方式来实现并发执行或延迟执行。异步处理通常用于处理耗时的操作,如网络请求、文件读写、定时器等,以避免阻塞主线程,提高程序的性能和响应速度。
const fetchRequest = () => { return new Promise((resolve, reject) => { // 发送请求, 在回调中处理结果 setTimeout(() =>{ resolve('接口返回成功') }, 1000); }) } fetchRequest().then((res) => { console.log(res); }) // 使用 Promise 发起一个异步的网络请求 const fetchRequest = () => { return new Promise((resolve, reject) => { // 发送请求/定时器, 在回调中处理结果 setTimeout(() =>{ resolve('接口返回成功') }, 1000); }) } fetchRequest().then((res) => { console.log(res); }) // 文件读写 // Node.js 提供了 fs 模块来处理文件的读写操作。要读取一个文本文件的内容,可以使用 fs.readFile 方法,具体示例如下: const fs = require('fs'); // 读取文件 fs.readFile('file.txt', 'utf8', (err, data) => { if (err) { console.error(err); return; } console.log(data); }); // Promise 的异步链式调用 const asyncTask1 = () => { return new Promise((resolve, reject) => { // 发送请求/定时器, 在回调中处理结果 setTimeout(() =>{ resolve('第一个任务执行完成') }, 1000); }) } const asyncTask2 = () => { return new Promise((resolve, reject) => { // 发送请求/定时器, 在回调中处理结果 setTimeout(() =>{ resolve('第二个任务执行完成') }, 1000); }) } asyncTask1().then((res) => { console.log(res); return asyncTask2() }).then((res) => { console.log(res); })
Promise 的源码解析可以帮助我们更深入地理解其内部实现原理。
以下是一个简化的 Promise 源码实现,用于说明 Promise 的基本工作原理
// Promise 构造函数 function PromiseDemo(executor) { this.status = 'pending'; // 初始状态为 pending this.value = undefined; // 成功时的返回值 this.reason = undefined; // 失败时的原因 this.onResolvedCallbacks = []; // 存储成功时的回调 this.onRejectedCallbacks = []; // 存储失败时的回调 const resolve = value => { if (this.status === 'pending') { this.status = 'fulfilled'; this.value = value; // 微任务:将成功态的回调放入微任务队列中 this.onResolvedCallbacks.forEach(function (fn) { return this.value = fn(); }); } }; const reject = reason => { if (this.status === 'pending') { this.status = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach(function (fn) { return this.value = fn(); }); } }; // 执行传入的 executor 函数,并传入 resolve 和 reject 作为参数 try { executor(resolve, reject); } catch (e) { reject(e); } } // then 方法 PromiseDemo.prototype.then = function (onFulfilled, onRejected) { const promise2 = new PromiseDemo((resolve, reject) => { if (this.status == "fulfilled") { console.log('1111111111') try { const x = onFulfilled(this.value) resolve(x) } catch (error) { reject(error) } } if (this.status == "rejected") { console.log('22222222222') try { const x = onRejected(this.reason) resolve(x) } catch (error) { reject(error) } } if (this.status == "pending") { console.log('3333333333333') this.onResolvedCallbacks.push(() => { if (this.status == "fulfilled") { try { const x = onFulfilled(this.value) resolve(x) } catch (error) { reject(error) } } }) this.onRejectedCallbacks.push(() => { if (this.status == "rejected") { try { const x = onRejected(this.reason) resolve(x) } catch (error) { reject(error) } } }) } else { console.log('444444444444') // 执行完所有回调函数之后,清空回调数组 this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; } }) return promise2; } PromiseDemo.prototype.catch = function (onRejected) { return this.then(null, onRejected) } // 示例使用 const promise = new PromiseDemo((resolve, reject) => { // 执行异步操作,并在合适的时机调用 resolve 或 reject // console.log(resolve, 'resolve') setTimeout(() => { resolve('返回成功'); }, 2000); }) promise .then(value => { console.log('成功:', value); return `${value}1` }) .then(value => { console.log('成功1:', value); })
class 声明Promise
class MyPromise { constructor(callback) { this.status = "pending"; this.value = ""; this.reason = ""; // 存储成功状态的回调函数 this.onResolvedCallbacks = []; // 存储失败状态的回调函数 this.onRejectedCallbacks = []; const resolve = (value) => { if (this.status == "pending") { this.status = "resolved" this.value = value; this.onResolvedCallbacks.forEach((fn) => fn()); } } const reject = (reason) => { if (this.status == "pending") { this.status = "rejected" this.reason = reason; this.onRejectedCallbacks.forEach((fn) => fn()); } } try { callback(resolve, reject); } catch (error) { reject(error); } } then(onResolved, onRejected) { onResolved = typeof onResolved === "function" ? onResolved : (value) => value; onRejected = typeof onRejected === "function" ? onRejected : (reason) => { throw reason }; // 创建一个新的 Promise 对象 const promise2 = new MyPromise((resolve, reject) => { // 如果当前 Promise 的状态为 resolved if (this.status == "resolved") { console.log('1111111111') try { // 执行 onResolved 回调函数 const x = onResolved(this.value) // 处理返回值 resolve(x) } catch (error) { // 如果回调函数抛出异常,将异常作为失败状态的值 reject(error) } } // 如果当前 Promise 的状态为 rejected if (this.status == "rejected") { console.log('2222222') try { // 执行 onRejected 回调函数 const x = onRejected(this.reason) // 处理返回值 resolve(x) } catch (error) { // 如果回调函数抛出异常,将异常作为失败状态的值 reject(error) } } // 如果当前 Promise 的状态为 pending if (this.status == "pending") { console.log('333333333333') // 将 onResolved 和 onRejected 保存起来 // 等待异步操作完成后再执行 this.onResolvedCallbacks.push(() => { if (this.status == "resolved") { try { // 将上一个then方法的返回值传递给下一个then方法 const x = onResolved(this.value) resolve(x) } catch (error) { reject(error) } } }) this.onRejectedCallbacks.push(() => { if (this.status == "rejected") { try { // 将上一个then方法的返回值传递给下一个then方法 const x = onRejected(this.reason) resolve(x) } catch (error) { reject(error) } } }) } else { // 执行完所有回调函数之后,清空回调数组 this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; } }) // 返回新的 Promise 对象 return promise2 } catch(onRejected) { return this.then(null, onRejected) } } const promise = new MyPromise((resolve, reject) => { // setTimeout(() => { // console.log('1') resolve('成功') // }, 1000) }) promise.then(1). then(value => { // console.log('2') // return "第一次" // setTimeout(() => { console.log('1', value) return "第一次" // },1000) }).then(value => { console.log('3', value) return "第二次" // return new MyPromise((resolve, reject) => { // setTimeout(() => { // resolve('第二次处理结果'); // }, 1000); // }); }).then(value => { console.log(value); // throw new Error('抛出异常'); }).catch(error => { console.log(error); }); export default MyPromise;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理