手写Promise
手写Promise
在本文中,我们通过手写实现一个符合Promise/A+规范的Promise来深入了解Promise, 而且手写Promise也是一道大厂面试常考题。在进入正题之前,推荐各位阅读一下Promise/A+规范 (网上有很多解释,可以自行搜索),这样才能更深入的理解本文中的代码。
实现一个简易版的Promise
先来搭建函数的大体框架
// 创建3个常量表示Promise的3个状态 const PENDING = ‘pending‘ const RESOLVED = ‘resolved‘ const REJECTED = ‘rejected‘ function MyPromise(fn){ // 创建常量that保存this, 因为Promise代码可能会异步执行,用于获取正确的this对象 const that = this // 一开始Promise的状态应该是pending this.state = PENDING // value变量用于保存resolve或者reject中传入的值 that.value = null // 用于保存then中的回调,因为当执行完Promise时状态可能还是等待中,这时候应该把 then 中的回调保存起来用于状态改变时使用 that.resolvedCallbacks = [] that.rejectedCallbacks = [] // 待完善 resolve 和 reject 函数 // 待完善执行 fn 函数 }
接下来完善resolve和reject函数,添加在MyPromise内部
// 待完善的 resolve 和 reject 函数 function resolve(value) { console.log(‘执行resolve‘) // 首先两个函数都得判断当前状态是否为等待中,因为规范规定只有等待态才可以改变状态 if (that.state === PENDING) { // // 将当前状态更改为对应状态,并且将传入的值赋值给value that.state = RESOLVED that.value = value // 状态改变时,指定回调 that.resolvedCallbacks.map(cb => cb(that.value)) } } function reject(value) { // 首先两个函数都得判断当前状态是否为等待中,因为规范规定只有等待态才可以改变状态 if (that.state === PENDING) { // 将当前状态更改为对应状态,并且将传入的值赋值给value that.state = REJECTED that.value = value // 状态改变时执行回调 that.rejectedCallbacks.map(cb => cb(that.value)) } }
完成以上两个函数后,就该实现如何执行Promise中传入的函数了
// 待完善执行 fn 函数 try { // 执行传入的参数并且将之前两个函数当做参数传进去 fn(resolve, reject) }catch (e) { // 可能执行函数过程中会遇到错误,需要捕获错误并且执行 reject 函数 reject(e) }
最后实现较为复杂的then函数
MyPromise.prototype.then = function (onFulfilled, onRejected) { console.log(‘执行then‘) const that = this // 判断两个参数是否为函数类型,因为这两个参数是可选参数,如果不是函数,则直接返回相应的value或reason onFulfilled = typeof onFulfilled === ‘function‘ ? onFulfilled : v => v onRejected = typeof onRejected === ‘function‘ ? onRejected : r => { throw r } // 当函数是等待态时,就往回调函数数组中push函数 if (that.state === PENDING) { console.log(‘Pending‘) that.resolvedCallbacks.push(onFulfilled) that.rejectedCallbacks.push(onRejected) } // 如果不是等待态,就执行相对应的函数 if (that.state === RESOLVED) { onFulfilled(that.value) } if (that.state === REJECTED) { onRejected(that.value) } }
最后,使用MyPromise
new MyPromise((resolve, reject) => { // 这里是异步,所以回调会先存入resolvedCallbacks中 setTimeout(() => { resolve(1) }, 0) }).then(value => { console.log(value) })
以上就是简单版的Promise实现,接下来实现更为完整版的Promise的解析。
相关推荐
nmgxzm00 2020-11-10
xixixi 2020-11-11
88254251 2020-11-01
MarukoMa 2020-09-02
88234852 2020-09-15
陈旭阳 2020-08-31
whynotgonow 2020-08-19
前端开发Kingcean 2020-07-30
whynotgonow 2020-07-29
bowean 2020-07-08
前端开发Kingcean 2020-07-08
88520191 2020-07-05
前端开发Kingcean 2020-06-27
88481456 2020-06-18
whynotgonow 2020-06-16
88520191 2020-06-13
88520191 2020-06-13
89500297 2020-06-13