一、什么是 Promise?
Promise 是目前 JS 异步编程的一种解决方案。
- 从语法上讲,
Promise是一个对象,从它可以获取异步操作的消息; - 从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
二、Promise 原理简析?
1、Promise 本身相当于一个状态机,拥有三种状态:
pending(等待态)fulfiled(成功态)rejected(失败态)
一个 Promise 对象初始化时的状态是 pending,调用了 resolve 后会将 Promise 的状态扭转为 fulfilled,调用 reject 后会将 Promise 的状态扭转为 rejected,这两种扭转一旦发生便不能再扭转该 Promise 到其他状态。
2、Promise 对象原型上有一个 then 方法,then 方法会返回一个新的 Promise 对象,并且将回调函数 return 的结果作为该 Promise resolve 的结果,then 方法会在一个 Promise 状态被扭转为 fulfilled 或 rejected 时被调用。then 方法的参数为两个函数,分别为 Promise 对象的状态被扭转为 fulfilled 和 rejected 对应的回调函数。
三、Promise 的使用?
构造一个 Promise 对象,并将要执行的异步函数传入到 Promise 的参数中执行,并且在异步执行结束后调用 resolve() 函数,就可以在 Promise 的 then 方法中获取到异步函数的执行结果
new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000)
}).then(
res => {},
err => {}
)
同时在 Promise 还为我们实现了很多方便使用的方法:
-
Promise.resolve方法Promise.resolve返回一个fulfilled状态的Promiseconst a = Promise.resolve(1) a.then( res => { // res = 1 }, err => {} ) -
Promise.all方法Promise.all接收一个Promise对象数组作为参数,只有全部的Promise都已经变为fulfilled状态后才会继续后面的处理。Promise.all本身返回的也是一个Promiseconst promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('promise1') }, 100) }) const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('promise2') }, 100) }) const promises = [promise1, promise2] Promise.all(promises).then( res => { // promises 全部变为 fulfilled 状态的处理 }, err => { // promises 中有一个变为 rejected 状态的处理 } ) -
Promise.race方法Promise.race和Promise.all类似,只不过这个函数会在Promise中第一个promise的状态扭转后就开始后面的处理(fulfilled、rejected均可)const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('promise1') }, 100) }) const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('promise2') }, 1000) }) const promises = [promise1, promise2] Promise.race(promises).then( res => { // 此时只有 promise1 resolve 了,promise2 仍处于 pending 状态 }, err => {} )
四、Promise 源码实现?
-
首先按照最基本的
Promise调用方式实现一个简单的Promise(基于 ES6 规范编写),假设我们有如下调用方式:new Promise((resolve, reject) => { setTimeout(() => { resolve(1) }, 1000) }) .then( res => { console.log(res) return 2 }, err => {} ) .then( res => { console.log(res) }, err => {} )我们首先要实现一个
Promise的类,这个类的构造函数会传入一个函数作为参数,并且向该函数传入resolve和reject两个方法。初始化
Promise的状态为pending。class MyPromise { constructor(executor) { this.executor = executor this.value = null this.status = 'pending' const resolve = value => { if (this.status === 'pending') { this.value = value // 调用 resolve 后记录 resolve 的值 this.status = 'fulfilled' // 调用 resolve 扭转 promise 状态 } } const reject = value => { if (this.status === 'pending') { this.value = value // 调用 reject 后记录 reject 的值 this.status = 'rejected' // 调用 reject 扭转 promise 状态 } } this.executor(resolve, reject) } -
接下来要实现
Promise对象上的then方法,then方法会传入两个函数作为参数,分别作为Promise对象resolve和reject的处理函数。这里要注意三点:
then函数需要返回一个新的Promise对象;- 执行
then函数的时候这个Promise的状态可能还没有被扭转为fulfilled或rejected; - 一个
Promise对象可以同时多次调用then函数;
class MyPromise { constructor(executor) { this.executor = executor this.value = null this.status = 'pending' this.onFulfilledFunctions = [] // 存放这个 promise 注册的 then 函数中传的第一个函数参数 this.onRejectedFunctions = [] // 存放这个 promise 注册的 then 函数中传的第二个函数参数 const resolve = value => { if (this.status === 'pending') { this.value = value this.status = 'fulfilled' this.onFulfilledFunctions.forEach(onFulfilled => { onFulfilled() // 将 onFulfilledFunctions 中的函数拿出来执行 }) } } const reject = value => { if (this.status === 'pending') { this.value = value this.status = 'rejected' this.onRejectedFunctions.forEach(onRejected => { onRejected() // 将 onRejectedFunctions 中的函数拿出来执行 }) } } this.executor(resolve, reject) } then(onFulfilled, onRejected) { const self = this if (this.status === 'pending') { /** * 当 promise 的状态仍然处于 ‘pending’ 状态时,需要将注册 onFulfilled、onRejected 方法放到 promise 的 onFulfilledFunctions、onRejectedFunctions 中备用 */ return new MyPromise((resolve, reject) => { this.onFulfilledFunctions.push(() => { const thenReturn = onFulfilled(self.value) resolve(thenReturn) }) this.onRejectedFunctions.push(() => { const thenReturn = onRejected(self.value) resolve(thenReturn) }) }) } else if (this.status === 'fulfilled') { return new MyPromise((resolve, reject) => { const thenReturn = onFulfilled(self.value) resolve(thenReturn) }) } else { return new MyPromise((resolve, reject) => { const thenReturn = onRejected(self.value) resolve(thenReturn) }) } } }对于以上完成的 MyPromise 进行测试,测试代码如下:
const mp = new MyPromise((resolve, reject) => { setTimeout(() => { resolve(1) }, 1000) }) mp.then(res => { console.log('first then', res) return res + 1 }).then(res => { console.log('first then', res) }) mp.then(res => { console.log(`second then`, res) return res + 1 }).then(res => { console.log(`second then`, res) }) /** * 输出结果如下: * first then 1 * first then 2 * second then 1 * second then 2 */ -
在
Promise相关的内容中,有一点常常被我们忽略,当then函数中返回的是一个Promise应该如何处理?考虑如下代码:
// 使用正确的 Promise new Promise((resolve, reject) => { setTimeout(() => { resolve() }, 1000) }) .then(res => { console.log('外部 promise') return new Promise((resolve, reject) => { resolve(`内部 promise`) }) }) .then(res => { console.log(res) }) /** * 输出结果如下: * 外部 promise * 内部 promise */通过以上的输出结果不难判断,当
then函数返回的是一个Promise时,Promise并不会直接将这个Promise传递到下一个then函数,而是会等待该Promise resolve后,将其resolve的值,传递给下一个then函数,找到我们实现的代码的then函数部分,做以下修改:then(onFulfilled, onRejected) { const self = this if (this.status === 'pending') { return new MyPromise((resolve, reject) => { this.onFulfilledFunctions.push(() => { const thenReturn = onFulfilled(self.value) if (thenReturn instanceof MyPromise) { // 当返回值为 promise 时,等该内部的 promise 状态扭转时,同步扭转外部的 promise 状态 thenReturn.then(resolve, reject) } else { resolve(thenReturn) } }) this.onRejectedFunctions.push(() => { const thenReturn = onRejected(self.value) if (thenReturn instanceof MyPromise) { // 当返回值为 promise 时,等该内部的 promise 状态扭转时,同步扭转外部的 promise 状态 thenReturn.then(resolve, reject) } else { resolve(thenReturn) } }) }) } else if (this.status === 'fulfilled') { return new MyPromise((resolve, reject) => { const thenReturn = onFulfilled(self.value) if (thenReturn instanceof MyPromise) { // 当返回值为 promise 时,等该内部的 promise 状态扭转时,同步扭转外部的 promise 状态 thenReturn.then(resolve, reject) } else { resolve(thenReturn) } }) } else { return new MyPromise((resolve, reject) => { const thenReturn = onRejected(self.value) if (thenReturn instanceof MyPromise) { // 当返回值为 promise 时,等该内部的 promise 状态扭转时,同步扭转外部的 promise 状态 thenReturn.then(resolve, reject) } else { resolve(thenReturn) } }) } } -
现在的
Promise实现代码仍然缺少很多细节逻辑,后面我还继续研究,来提供一个相对完整的版本。
参考文章:https://blog.csdn.net/weixin_56134381/article/details/115868041

847

被折叠的 条评论
为什么被折叠?



