赞
踩
Promise
是目前 JS 异步编程的一种解决方案。
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
的参数中执行,并且在异步执行结束后调用 resolve()
函数,就可以在 Promise
的 then
方法中获取到异步函数的执行结果
new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000)
}).then(
res => {},
err => {}
)
同时在 Promise
还为我们实现了很多方便使用的方法:
Promise.resolve
方法
Promise.resolve
返回一个 fulfilled
状态的 Promise
const a = Promise.resolve(1)
a.then(
res => {
// res = 1
},
err => {}
)
Promise.all
方法
Promise.all
接收一个 Promise
对象数组作为参数,只有全部的 Promise
都已经变为 fulfilled
状态后才会继续后面的处理。Promise.all
本身返回的也是一个 Promise
const 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
(基于 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。