深入理解JavaScript:手写Promise实现原理

需积分: 5 0 下载量 200 浏览量 更新于2024-11-16 收藏 1KB ZIP 举报
知识点一:Promise基本概念 Promise是JavaScript中处理异步操作的一个核心概念,它代表了一个可能尚未完成,但预期在未来某个时间点能够完成的异步操作的结果。Promise有三种状态:pending(等待中)、fulfilled(已成功)和rejected(已失败)。状态一旦改变,就不会再变。 知识点二:Promise的方法 Promise的主要方法包括then()、catch()、finally()。then()方法可以接受两个参数,分别是状态变为fulfilled时和rejected时要执行的函数。catch()方法则是then(null, rejectionHandler)的语法糖,专门用来处理拒绝的情况。finally()方法无论Promise被解决或被拒绝都会执行。 知识点三:Promise的构造函数 Promise是通过构造函数创建的,构造函数接收一个执行器函数(executor)作为参数。执行器函数又接受两个参数,通常命名为resolve和reject,这两个参数也是函数。当异步操作执行成功时,调用resolve(value),Promise的状态变为fulfilled;当异步操作失败时,调用reject(reason),Promise的状态变为rejected。 知识点四:手写Promise的步骤 要实现一个简化版的Promise,需要理解几个关键点: 1. 实现一个构造函数,可以接收一个执行器函数。 2. 构造函数内部需要有状态保存的变量,以及成功和失败的回调函数列表。 3. 实现resolve和reject函数,用于改变Promise的状态,并将相应回调函数加入到队列中。 4. then()方法需要实现两个回调函数的注册,并且处理链式调用的情况。 5. 需要处理异步逻辑,即确保then()注册的回调函数在下一个事件循环中执行。 知识点五:Promise的链式调用 Promise的链式调用是通过then()方法实现的。当then()中返回一个新的Promise对象时,下一个then()的调用会等待这个新的Promise对象被解决或被拒绝。如果then()方法中返回的是一个非Promise值,则这个值会被包装在一个解决状态的Promise中。 知识点六:Promise的异常处理 Promise的异常处理主要通过catch()方法和then()方法的第二个参数来实现。在Promise链的任何位置抛出的错误,都可以被就近的catch()捕获。如果没有就近的catch()捕获,则错误会被传递到下一个then()的第二个参数中。如果整个Promise链没有捕获到错误,则在全局范围内会被捕获。 知识点七:Promise的其他特性 - Promise.all()方法用于处理多个Promise对象的并行执行,只有所有的Promise都成功解决时才解决,否则任何一个Promise被拒绝就立即拒绝。 - Promise.race()方法用于处理多个Promise对象的竞态执行,第一个完成的Promise的状态会被采纳。 - Promise.resolve()和Promise.reject()是用于创建已经解决或已拒绝的Promise的静态方法。 知识点八:手写Promise的代码实现 以下是一个简化版Promise的手写示例代码(main.js中的内容): ```javascript // Promise构造函数 function MyPromise(executor) { // 初始状态 var self = this; self.state = 'pending'; self.value = null; self.reason = null; // 成功的回调队列 self.onFulfilledCallbacks = []; // 失败的回调队列 self.onRejectedCallbacks = []; // resolve函数 function resolve(data) { // 成功状态只能改变一次 if(self.state === 'pending') { self.state = 'fulfilled'; self.value = data; // 执行成功的回调 self.onFulfilledCallbacks.forEach(fn => fn(data)); } } // reject函数 function reject(data) { // 失败状态只能改变一次 if(self.state === 'pending') { self.state = 'rejected'; self.reason = data; // 执行失败的回调 self.onRejectedCallbacks.forEach(fn => fn(data)); } } try { // 立即执行executor,并传入resolve和reject函数 executor(resolve, reject); } catch (error) { // 如果执行出错,直接执行reject reject(error); } } // MyPromise.prototype.then()方法 MyPromise.prototype.then = function(onFulfilled, onRejected) { // 调用时传入的参数不一定是函数,需要进行判断 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : data => data; onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error; }; var self = this; var promise2; if(self.state === 'fulfilled') { // 状态为fulfilled时,直接执行onFulfilled,并返回新的Promise return promise2 = new MyPromise(function(resolve, reject) { setTimeout(function() { try { var x = onFulfilled(self.value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }); }); } if(self.state === 'rejected') { // 状态为rejected时,直接执行onRejected,并返回新的Promise return promise2 = new MyPromise(function(resolve, reject) { setTimeout(function() { try { var x = onRejected(self.reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }); }); } if(self.state === 'pending') { // 状态为pending时,将onFulfilled和onRejected注册为回调函数 return promise2 = new MyPromise(function(resolve, reject) { self.onFulfilledCallbacks.push(function(value) { try { var x = onFulfilled(value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }); self.onRejectedCallbacks.push(function(reason) { try { var x = onRejected(reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }); }); } }; // resolvePromise函数用于处理then方法返回值的情况 function resolvePromise(promise2, x, resolve, reject) { if(promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise')); } if((typeof x === 'object' && x !== null) || typeof x === 'function') { try { var then = x.then; if(then === function) { x.then(resolve, reject); } else if(typeof then === 'function') { var called; try { then.call(x, function resolvePromiseResult(y) { if(called) return; called = true; resolvePromise(promise2, y, resolve, reject); }, function rejectPromiseResult(r) { if(called) return; called = true; reject(r); }); } catch(error) { if(called) return; called = true; reject(error); } } else { resolve(x); } } catch(error) { reject(error); } } else { resolve(x); } } // 打印README.txt中的内容 const fs = require('fs'); fs.readFile('./README.txt', 'utf8', (err, data) => { if(err) throw err; console.log(data); }); ``` 知识点九:实现Promise时的注意事项 - 确保Promise状态一旦改变就不再变化。 - 确保resolve和reject函数的正确使用,以及错误的捕获。 - 确保异步逻辑的正确处理,使得then()中的回调函数在下一个事件循环执行。 - 对于then()方法返回值的处理,需要使用resolvePromise函数来处理。 - 对于catch()方法的实现,确保其能够捕获到链中的任何错误。 以上内容将帮助开发者全面掌握手写Promise的技巧,深入理解其内部机制,并能够在实际开发中灵活应用。"
2025-02-16 上传