学习笔记 手写 Promise
文章目录
- 学习笔记 手写 Promise
- 前言
- 一、Promise 基本功能的实现
- 二、Promise 内部异步逻辑的实现
- 三、Promise.then 方法多次调用添加多个处理函数的实现
- 四、Promise.then 方法的链式调用的实现(一)
- 五、Promise.then 方法的链式调用的实现(二)
- 六、Promise.then 方法的链式调用识别自身的实现
- 七、Promise 捕获错误的实现
- 八、Promise.then 方法的参数变成可选参数的实现
- 九、Promise.all 方法的实现
- 十、Promise.resolve 方法的实现
- 十一、Promise.finally 方法的实现
- 十二、Promise.catch 方法的实现
- 十三、Promise.reject 方法的实现
- 十四、Promise.race 方法的实现
- 总结
前言
Promise基本功能、Promise.then()、Promise.reject()、Promise.resolve()、Promise.catch()、Promise.finally()、Promise.all()、Promise.race()、Promise.then()链式调用、Promise.then()参数可选的实现
一、Promise 基本功能的实现
Promise示例:
let promise = new Promise((resolve, reject) => {
resolve('成功')
// reject('失败')
});
promise.then(value => console.log(value), reason => console.log(reason))
// 结果:
// resolve('成功') ----> 成功
// reject('失败') ----> 失败
1. 实现思路
-
Promise是一个类,可以使用 new 来调用 Promise 的构造器来进行实例化;
-
在执行这个类的时候,需要传递一个带有 resolve(解析)和 reject(拒绝)两个参数的执行器进去,执行器会立即执行;
-
在 Promise 中有三种状态,分别为pending(等待 )、fulfilled(成功 )、 rejected(失败);
-
resolve 和 reject 函数是用来更改状态的(状态一旦确定,就不能更改)
resolve:pending(等待) ====> fulfilled(成功)
reject:pending(等待) ====> rejected(失败) -
then 方法内部做的事情就是判断状态,then 方法是被定义在原型变量中的。
如果状态是成功,调用成功回调函数;
如果状态是失败,调用失败回调函数。 -
then成功回调有一个参数,表示成功之后的值;
then失败回调有一个参数,表示失败之后的原因。
2. MyPromise实现
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
}
// 状态,初始值为 pending(等待)
status = PENDING
// 保存成功的值,默认 undefined
value = undefined
// 保存失败的值,默认 undefined
reason = undefined
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
}
then = (successCallBack, failCallBack) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 状态为成功,调用成功回调函数
successCallBack(this.value)
} else if (this.status === REJECTED) {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
}
}
}
let promise = new MyPromise((resolve, reject) => {
// resolve('成功')
reject('失败')
});
promise.then(value => console.log(value), reason => console.log(reason))
// 结果:
// resolve('成功') ----> 成功
// reject('失败') ----> 失败
二、Promise 内部异步逻辑的实现
Promise内部异步示例:
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('成功'), 2000)
// setTimeout(() => reject('失败'), 2000)
});
promise.then(value => console.log(value), reason => console.log(reason))
// 结果:
// setTimeout(() => resolve('成功'), 2000) ----> 2秒后打印 成功
// setTimeout(() => reject('失败'), 2000) ----> 2秒后打印 失败
1. 问题产生
MyPromise内部使用异步:
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => resolve('成功'), 2000)
// setTimeout(() => reject('失败'), 2000)
});
promise.then(value => console.log(value), reason => console.log(reason))
// 结果:
// setTimeout(() => resolve('成功'), 2000) ----> 没东西打印出来
// setTimeout(() => reject('失败'), 2000) ----> 没东西打印出来
- 这时候发现自己的实现的MyPromise输出结果没有跟Promise的一样
问题分析: new MyPromise( ‘执行器’ ) 中的 ‘执行器’ 会立即执行,当 ‘执行器’执行的时候,会发现里面的代码是异步代码,异步代码会被挂载到 ‘消息队列’ 中,主线程不会等待两秒,会继续执行直到没有任务,再去执行 ‘消息队列’ 的任务,所以promise.then( ‘内容’ )里面的 ‘内容’ 会马上被执行。上述MyPromise里的 then 只判断了两种状态(‘fulfilled(成功)’ 和 ‘rejected(失败)’,没有判断 'pending(等待)'状态,并且promise两秒钟后才改变状态,这时的状态是 ‘pending(等待)’;两秒钟后才resolve,这时then早就已经执行完毕了,所以不会打印结果出来。
解决方案: MyPromise里的 then 增加状态 ‘pending(等待)’ 状态的判断。
2. MyPromise 内部异步实现
MyPromise 增加内部异步:
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = undefined
// 保存失败回调
failCallBack = undefined
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
this.successCallBack && this.successCallBack(this.value)
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
this.failCallBack && this.failCallBack(this.reason)
}
then = (successCallBack, failCallBack) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 状态为成功,调用成功回调函数
successCallBack(this.value)
} else if (this.status === REJECTED) {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack = successCallBack
this.failCallBack = failCallBack
}
}
}
let promise = new MyPromise((resolve, reject) => {
// resolve('成功')
// reject('失败')
setTimeout(() => resolve('成功'), 2000)
// setTimeout(() => resolve('成功'), 2000)
});
promise.then(value => console.log(value), reason => console.log(reason))
// 结果:
// resolve('成功') ----> 成功
// reject('失败') ----> 失败
// setTimeout(() => resolve('成功'), 2000) ----> 2秒后打印 成功
// setTimeout(() => reject('失败'), 2000) ----> 2秒后打印 失败
三、Promise.then 方法多次调用添加多个处理函数的实现
Promise then 方法多次调用示例:
let promise = new Promise((resolve, reject) => {
// setTimeout(() => resolve('成功'), 2000)
resolve('成功')
// reject('失败')
});
promise.then(value => console.log(value), reason => console.log(reason))
promise.then(value => console.log(value), reason => console.log(reason))
promise.then(value => console.log(value), reason => console.log(reason))
// 结果:
// setTimeout(() => resolve('成功'), 2000) ----> 两秒钟后打印 成功 成功 成功
// resolve('成功') ----> 成功 成功 成功
// reject('失败') ----> 失败 失败 失败
1. 问题产生
MyPromise then 方法多次调用示例:
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => resolve('成功'), 2000)
// setTimeout(() => reject('失败'), 2000)
});
promise.then(value => console.log(value), reason => console.log(reason))
// 结果:
// setTimeout(() => resolve('成功'), 2000) ----> 两秒钟后打印 成功
// resolve('成功') ----> 成功 成功 成功
// reject('失败') ----> 失败 失败 失败
- 这时候发现自己的实现的MyPromise输出结果没有跟Promise的一样,在异步调用时候没有 输出 三次 ‘成功’
问题分析: 在 MyPromise( ‘执行器’ ) then中异步调用中,因为之前 successCallBack = undefined、failCallBack = undefined 只能存储一个函数,多个异步调用会覆盖掉之前的,只保留最后的一个。
解决方案: 将 MyPromise里的successCallBack 和 failCallBack 变成数组,successCallBack = [ ]、failCallBack = [ ]。
2. MyPromise.then 方法多次调用实现
MyPromise 增加 then 方法多次调用:
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
while (this.successCallBack.length) this.successCallBack.shift()(this.value)
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
}
then = (successCallBack, failCallBack) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 状态为成功,调用成功回调函数
successCallBack(this.value)
} else if (this.status === REJECTED) {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(successCallBack)
this.failCallBack.push(failCallBack)
}
}
}
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => resolve('成功'), 2000)
// resolve('成功')
// reject('失败')
});
promise.then(value => console.log(value), reason => console.log(reason))
promise.then(value => console.log(value), reason => console.log(reason))
promise.then(value => console.log(value), reason => console.log(reason))
// 结果:
// setTimeout(() => resolve('成功'), 2000) ----> 两秒钟后打印 成功
// resolve('成功') ----> 成功 成功 成功
// reject('失败') ----> 失败 失败 失败
四、Promise.then 方法的链式调用的实现(一)
Promise then 方法链式调用示例:
let promise = new Promise((resolve, reject) => {
// setTimeout(() => resolve('成功'), 2000)
resolve('成功')
// reject('失败')
});
promise
.then(value => {
console.log(value)
return 123
})
.then(value => console.log(value))
// 结果:
// 成功
// 100
- then方法是可以被链式调用的, 后面then方法的回调函数拿到值的是上一个then方法的回调函数的返回值
1. 实现思路
- then方法是promise对象实现调用的,如果想实现then链式调用,那么promise返回的值也应该是promise对象
2. 实现Promise.then 方法链式链式调用
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
while (this.successCallBack.length) this.successCallBack.shift()(this.value)
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
}
then = (successCallBack, failCallBack) => {
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
resolve(x)
} else if (this.status === REJECTED) {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(successCallBack)
this.failCallBack.push(failCallBack)
}
})
return promise2
}
}
let promise = new MyPromise((resolve, reject) => {
resolve('成功')
});
promise
.then(value => {
console.log(value)
return 123
})
.then(value => console.log(value))
// 结果:
// 成功
// 100
五、Promise.then 方法的链式调用的实现(二)
- 在Promise then 方法的链式调用的时候,可以返回一个普通值,也可以返回一个 promise 对象。
- 如果返回的是一个值可以直接调用 resolve(),传递给下一个promise 对象。
- 如果返回的是一个 promise 对象,要先查看这个promise 对象的状态(status)。若返回的 promise 对象的状态是 fulfilled 则调用resolve方法,把成功的结果传递给下一个对象;若返回的 promise 对象的状态是 rejected 则调用 reject 方法,把失败的原因传递给下一个对象。
MyPromise then 方法链式调用示例:
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
while (this.successCallBack.length) this.successCallBack.shift()(this.value)
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
}
then = (successCallBack, failCallBack) => {
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(x, resolve, reject)
} else if (this.status === REJECTED) {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(successCallBack)
this.failCallBack.push(failCallBack)
}
})
return promise2
}
}
function resolvePromise (x, resolve, reject) {
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 测试
let promise = new MyPromise((resolve, reject) => {
resolve('成功')
});
function other () {
return new MyPromise((resolve, reject) => {
resolve('other')
})
}
promise
.then(value => {
console.log(value)
return other()
})
.then(value => console.log(value))
// 结果:
// 成功
// other
六、Promise.then 方法的链式调用识别自身的实现
Promise then 方法调用自身 示例:
let promise = new Promise((resolve, reject) => {
resolve('成功')
});
let p1 = promise
.then(value => {
console.log(value)
return p1
})
// p1.then(() => { }, reason => console.log(reason.message))
// 结果:
// 成功
// Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise> // 报错
// p1.then(() => { }, reason => console.log(reason.message)) // 会输出错误的信息
MyPromise then 方法调用识别自身 示例:
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
while (this.successCallBack.length) this.successCallBack.shift()(this.value)
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
}
then = (successCallBack, failCallBack) => {
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 把这部分的代码变成异步,才能正常获取promise2
setTimeout(() => {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
}, 0)
} else if (this.status === REJECTED) {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(successCallBack)
this.failCallBack.push(failCallBack)
}
})
return promise2
}
}
function resolvePromise (promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 测试
let promise = new MyPromise((resolve, reject) => {
resolve('成功')
});
let p1 = promise.then(value => {
console.log(value)
return p1
})
p1.then(value => console.log(value), reason => console.log(reason.message))
// 结果:
// 成功
// Chaining cycle detected for promise #<Promise> // 报错信息
七、Promise 捕获错误的实现
Promise then 方法捕获错误 示例:
// 情况一
let promise = new MyPromise((resolve, reject) => {
throw TypeError('抛出一个错误')
resolve('成功')
});
promise.then(value => console.log(value), reason => console.log(reason.message))
// 结果:
// 抛出一个错误 // 报错
// 情况二
let promise2 = new Promise((resolve, reject) => {
resolve('成功')
});
promise2
.then(value => {
console.log(value)
throw TypeError('抛出一个错误')
console.log('123')
}, reason => {
console.log(reason)
}).then(value => console.log(value), reason => console.log(reason.message))
// 结果:
// 成功
// 抛出一个错误 // 报错
1. 实现思路
- 情况一:在 MyPromise 类的构造函数中增加 try catch 异常捕获
- 情况二:在 MyPromise 的 then 方法中 成功回调、失败回调、异步回调 增加 try catch 异常捕获
2. 实现捕获错误
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
try {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
// while (this.successCallBack.length) this.successCallBack.shift()(this.value)
while (this.successCallBack.length) this.successCallBack.shift()()
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
// while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()()
}
then = (successCallBack, failCallBack) => {
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 把这部分的代码变成异步,才能正常获取promise2
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(() => {
// successCallBack()
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.failCallBack.push(() => {
setTimeout(() => {
// failCallBack()
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
}
function resolvePromise (promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 打印出的结果会有异步情况的出现
// 测试一
let promise1 = new MyPromise((resolve, reject) => {
throw new Error('抛出一个错误')
resolve('成功')
});
promise1
.then(value => console.log('测试一', value), reason => console.log('测试一', reason.message))
// 测试一 结果:
// 抛出一个错误
// 测试二 成功
let promise2 = new MyPromise((resolve, reject) => {
// throw new Error('抛出一个错误')
resolve('成功')
});
promise2
.then(value => {
console.log('测试二', value)
throw new Error('抛出一个错误')
}, reason => console.log('测试二', reason.message))
.then(value => console.log('测试二', value), reason => console.log('测试二', reason.message))
// 测试二 结果:
// 测试二 成功
// 测试二 抛出一个错误
// 测试三 失败
let promise3 = new MyPromise((resolve, reject) => {
reject('失败')
});
promise3
.then(value => {
console.log('测试三', value)
}, reason => {
console.log('测试三', reason)
throw new Error('抛出一个错误')
})
.then(value => console.log('测试三', value), reason => console.log('测试三', reason.message))
// 测试三 结果:
// 测试三 失败
// 测试三 抛出一个错误
// 测试四 异步
let promise4 = new MyPromise((resolve, reject) => {
setTimeout(() => resolve('成功'), 2000)
});
promise4
.then(value => {
console.log('测试四', value)
throw new Error('抛出一个错误')
// return 'aaaa'
}, reason => {
console.log('测试四', reason)
})
.then(value => console.log('测试四', value), reason => console.log('测试四', reason.message))
// 测试四 结果: 两秒钟后打印
// 测试四 成功
// 测试四 抛出一个错误
八、Promise.then 方法的参数变成可选参数的实现
Promise then 方法的参数可选 示例:
let promise = new Promise((resolve, reject) => {
resolve('成功')
});
promise.then().then().then(value => console.log(value))
// 结果:
// 成功
1. 实现思路
let promise = new Promise((resolve, reject) => {
resolve('成功')
});
promise
.then(value => value)
.then(value => value)
.then(value => console.log(value))
// 结果:
// 成功
- 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给 successCallBack
- 判断 failCallBack 是否存在,存在则直接调用 failCallBack,否则 reason => { throw reason } 重新赋值给 failCallBack
2. 实现 Promise.then 方法的参数变成可选参数示例
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
try {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
// while (this.successCallBack.length) this.successCallBack.shift()(this.value)
while (this.successCallBack.length) this.successCallBack.shift()()
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
// while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()()
}
then = (successCallBack, failCallBack) => {
// 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
successCallBack = successCallBack ? successCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 把这部分的代码变成异步,才能正常获取promise2
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(() => {
// successCallBack()
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.failCallBack.push(() => {
setTimeout(() => {
// failCallBack()
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
}
function resolvePromise (promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 测试
let promise1 = new MyPromise((resolve, reject) => {
// throw new Error('抛出一个错误')
resolve('成功')
// reject('失败')
});
promise1
.then()
.then()
.then(value => console.log(value), reason => console.log(reason))
// 结果:
// resolve('成功') ----> 成功
// reject('失败') ----> 失败
// throw new Error('抛出一个错误') ----> Error: 抛出一个错误
九、Promise.all 方法的实现
Promise.all 方法示例:
function p1() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('p1'), 2000)
})
}
function p2() {
return new Promise((resolve, reject) => {
resolve('p2')
})
}
Promise.all(['a', 'b', p1(), p2(), 'c']).then(result => console.log(result))
// 结果:两秒钟后打印
// ["a", "b", "p1", "p2", "c"]
- Promise.all 接收的是一个数组,返回的也是一个Promise 对象。
- 假如出入所有传入所有Promise 对象返回的结果都是成功的,那么Promise.all 返回的结果也是成功的。
- 假如出入所有传入所有Promise 对象返回的结果其中一个是失败的,那么Promise.all 返回的结果是失败的。
实现 Promise.all 方法基本示例:
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
... 这部分代码没修改 ...
static all (array) {
// 声明一个结果数组
let result = []
// 结果数组添加结果方法
function addData (key, value) {
result[key] = value
}
// 返回 Promise 对象
return new MyPromise((resolve, reject) => {
// 遍历传进来的数组
for (let i = 0; i < array.length; i++) {
// 获取数组当前的值
let current = array[i];
// 判断当前的值是否为 Promise 对象
if (current instanceof MyPromise) {
// Promise 对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值,直接添加到结果数组中
addData(i, current)
}
}
resolve(result)
})
}
}
function resolvePromise (promise2, x, resolve, reject) {
... 这部分代码没修改 ...
}
// 测试:
function p1 () {
return new MyPromise((resolve, reject) => {
setTimeout(() => resolve('p1'), 2000)
})
}
function p2 () {
return new MyPromise((resolve, reject) => {
resolve('p2')
})
}
MyPromise.all(['a', 'b', p1(), p2(), 'c']).then(result => console.log(result))
// 结果:直接打印
// ['a', 'b', <1 empty item>, 'p2', 'c']
// 预想结果: 两秒钟后打印
// ['a', 'b', 'p1', 'p2', 'c']
- 返回结果有一个空值(<1 empty item>)
原因分析: 执行MyPromise.all 时 执行 for 循环期间 p1 是异步操作的,循环是没有等待异步操作的,直接调用 resolve(result) ,这是 p1 的结果还没出来,所以会有一个 空值
实现 Promise.all 方法完整示例
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
try {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
// while (this.successCallBack.length) this.successCallBack.shift()(this.value)
while (this.successCallBack.length) this.successCallBack.shift()()
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
// while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()()
}
then = (successCallBack, failCallBack) => {
// 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
successCallBack = successCallBack ? successCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 把这部分的代码变成异步,才能正常获取promise2
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(() => {
// successCallBack()
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.failCallBack.push(() => {
setTimeout(() => {
// failCallBack()
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
static all (array) {
// 声明一个结果数组
let result = []
let index = 0
// 返回 Promise 对象
return new MyPromise((resolve, reject) => {
// 结果数组添加结果方法
function addData (key, value) {
result[key] = value
index++
if (index == array.length) {
// 当结果的长度和传进来的长度相等时才返回所有结果
resolve(result)
}
}
// 遍历传进来的数组
for (let i = 0; i < array.length; i++) {
// 获取数组当前的值
let current = array[i];
// 判断当前的值是否为 Promise 对象
if (current instanceof MyPromise) {
// Promise 对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值,直接添加到结果数组中
addData(i, current)
}
}
})
}
}
function resolvePromise (promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 测试一
function p1 () {
return new MyPromise((resolve, reject) => {
setTimeout(() => resolve('p1'), 2000)
})
}
function p2 () {
return new MyPromise((resolve, reject) => {
resolve('p2')
})
}
MyPromise.all(['a', 'b', p1(), p2(), 'c']).then(result => console.log(result))
// 结果:直接打印
// ['a', 'b', 'p1', 'p2', 'c']
十、Promise.resolve 方法的实现
- Promise.resolve 方法是给指定的值转换成Promsie对象
Promise.resolve 方法示例:
function p1() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('p1'), 2000)
})
}
Promise.resolve(12).then(result => console.log(result))
Promise.resolve(p1()).then(result => console.log(result))
// 结果:
// 12
// p1 // 两秒钟后打印
实现 Promise.resolve 方法
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
try {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
// while (this.successCallBack.length) this.successCallBack.shift()(this.value)
while (this.successCallBack.length) this.successCallBack.shift()()
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
// while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()()
}
then = (successCallBack, failCallBack) => {
// 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
successCallBack = successCallBack ? successCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 把这部分的代码变成异步,才能正常获取promise2
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(() => {
// successCallBack()
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.failCallBack.push(() => {
setTimeout(() => {
// failCallBack()
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
static all (array) {
// 声明一个结果数组
let result = []
let index = 0
// 返回 Promise 对象
return new MyPromise((resolve, reject) => {
// 结果数组添加结果方法
function addData (key, value) {
result[key] = value
index++
if (index == array.length) {
// 当结果的长度和传进来的长度相等时才返回所有结果
resolve(result)
}
}
// 遍历传进来的数组
for (let i = 0; i < array.length; i++) {
// 获取数组当前的值
let current = array[i];
// 判断当前的值是否为 Promise 对象
if (current instanceof MyPromise) {
// Promise 对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值,直接添加到结果数组中
addData(i, current)
}
}
})
}
static resolve (value) {
// 是MyPromise对象直接返回的
if (value instanceof MyPromise) return value
// 不是对象,创建一个MyPromise,把 resolve(value) 返回
return new MyPromise(resolve => resolve(value))
}
}
function resolvePromise (promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 测试一
function p1 () {
return new MyPromise((resolve, reject) => {
setTimeout(() => resolve('p1'), 2000)
})
}
MyPromise.resolve(12).then(result => console.log(result))
MyPromise.resolve(p1()).then(result => console.log(result))
// 结果:
// 12
// p1 // 两秒钟后打印
十一、Promise.finally 方法的实现
- Promise.finally 方法无论当前状态是成功还是失败,走回执行一次
- Promise.finally 方法可以使用 .then() 拿到当前Promise 对象最终返回的结果
Promise.finally 方法示例:
function p1() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('p1'), 2000)
})
}
Promise.resolve(12).then(result => console.log(result))
Promise.resolve(p1()).then(result => console.log(result))
// 结果:
// 12
// p1 // 两秒钟后打印
Promise.finally 方法基本示例:
class MyPromise {
... 这部分代码没修改 ...
finally (callback) {
// 调用 this.then 获取当前状态
// this.then(() => { callback() }, () => { callback() })
// finally 返回的也是 Promise 对象
return this.then(value => {
callback()
return value
}, reason => {
callback()
throw reason
})
}
}
// 测试
function p1 () {
return new MyPromise((resolve, reject) => {
setTimeout(() => resolve('p1'), 2000)
})
}
function p2 () {
return new MyPromise((resolve, reject) => {
resolve('p2 resolve')
// reject('p2 reject')
})
}
p2().finally(() => {
console.log('finally');
// return p1()
}).then(value => console.log(value), reason => console.log(reason))
// 结果:
// finally
// p2 resolve
// finally 里面 return p1() ,直接打印结果,没有延迟两秒钟
// finally
// p2 resolve
实现 Promise.finally 方法完整示例
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
try {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
// while (this.successCallBack.length) this.successCallBack.shift()(this.value)
while (this.successCallBack.length) this.successCallBack.shift()()
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
// while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()()
}
then = (successCallBack, failCallBack) => {
// 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
successCallBack = successCallBack ? successCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 把这部分的代码变成异步,才能正常获取promise2
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(() => {
// successCallBack()
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.failCallBack.push(() => {
setTimeout(() => {
// failCallBack()
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
finally (callback) {
// 调用 this.then 获取当前状态
// this.then(() => { callback() }, () => { callback() })
// finally 返回的也是 Promise 对象
return this.then(value => {
// callback()
// return value
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
// callback()
// throw reason
return MyPromise.reject(callback()).then(() => { throw reason })
})
}
static all (array) {
// 声明一个结果数组
let result = []
let index = 0
// 返回 Promise 对象
return new MyPromise((resolve, reject) => {
// 结果数组添加结果方法
function addData (key, value) {
result[key] = value
index++
if (index == array.length) {
// 当结果的长度和传进来的长度相等时才返回所有结果
resolve(result)
}
}
// 遍历传进来的数组
for (let i = 0; i < array.length; i++) {
// 获取数组当前的值
let current = array[i];
// 判断当前的值是否为 Promise 对象
if (current instanceof MyPromise) {
// Promise 对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值,直接添加到结果数组中
addData(i, current)
}
}
})
}
static resolve (value) {
// 是MyPromise对象直接返回的
if (value instanceof MyPromise) return value
// 不是对象,创建一个MyPromise,把 resolve(value) 返回
return new MyPromise(resolve => resolve(value))
}
}
function resolvePromise (promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 测试
function p1 () {
return new MyPromise(function (resolve, reject) {
setTimeout(function () {
resolve('p1')
}, 2000)
})
}
function p2 () {
return new MyPromise((resolve, reject) => {
resolve('p2 resolve')
// reject('p2 reject')
})
}
p2().finally(() => {
console.log('finally');
return p1()
}).then(value => console.log(value), reason => console.log(reason))
// 结果:
// finally 里面 return p1() 两秒钟后打印
// finally
// p2 resolve
十二、Promise.catch 方法的实现
Promise.catch 方法示例:
let promise = new Promise((resolve, reject) => {
// setTimeout(() => resolve('成功'), 2000)
reject('失败')
});
promise.catch(reason => console.log(reason))
// 结果:
// 失败
实现 Promise.catch 方法
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
try {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
// while (this.successCallBack.length) this.successCallBack.shift()(this.value)
while (this.successCallBack.length) this.successCallBack.shift()()
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
// while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()()
}
then = (successCallBack, failCallBack) => {
// 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
successCallBack = successCallBack ? successCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 把这部分的代码变成异步,才能正常获取promise2
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(() => {
// successCallBack()
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.failCallBack.push(() => {
setTimeout(() => {
// failCallBack()
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
finally (callback) {
// 调用 this.then 获取当前状态
// this.then(() => { callback() }, () => { callback() })
// finally 返回的也是 Promise 对象
return this.then(value => {
// callback()
// return value
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
// callback()
// throw reason
return MyPromise.reject(callback()).then(() => { throw reason })
})
}
catch (failCallBack) {
return this.then(undefined, failCallBack)
}
static all (array) {
// 声明一个结果数组
let result = []
let index = 0
// 返回 Promise 对象
return new MyPromise((resolve, reject) => {
// 结果数组添加结果方法
function addData (key, value) {
result[key] = value
index++
if (index == array.length) {
// 当结果的长度和传进来的长度相等时才返回所有结果
resolve(result)
}
}
// 遍历传进来的数组
for (let i = 0; i < array.length; i++) {
// 获取数组当前的值
let current = array[i];
// 判断当前的值是否为 Promise 对象
if (current instanceof MyPromise) {
// Promise 对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值,直接添加到结果数组中
addData(i, current)
}
}
})
}
static resolve (value) {
// 是MyPromise对象直接返回的
if (value instanceof MyPromise) return value
// 不是对象,创建一个MyPromise,把 resolve(value) 返回
return new MyPromise(resolve => resolve(value))
}
}
function resolvePromise (promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 测试
function p2 () {
return new MyPromise((resolve, reject) => {
// resolve('p2 resolve')
reject('p2 reject')
})
}
p2().then(value => console.log(value)).catch(reason => console.log('catch ', reason))
// 结果:
// catch p2 reject
十三、Promise.reject 方法的实现
Promise reject 方法示例:
Promise.resolve(12).then(result => console.log(result))
// 结果:
// 12
实现 Promise reject 方法
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
try {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
// while (this.successCallBack.length) this.successCallBack.shift()(this.value)
while (this.successCallBack.length) this.successCallBack.shift()()
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// console.log('this.reason', this.reason);
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
// while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()()
}
then = (successCallBack, failCallBack) => {
// 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
successCallBack = successCallBack ? successCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 把这部分的代码变成异步,才能正常获取promise2
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(() => {
// successCallBack()
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.failCallBack.push(() => {
setTimeout(() => {
// failCallBack()
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
finally (callback) {
// 调用 this.then 获取当前状态
// this.then(() => { callback() }, () => { callback() })
// finally 返回的也是 Promise 对象
return this.then(value => {
// callback()
// return value
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
// callback()
// throw reason
return MyPromise.reject(callback()).then(() => { throw reason })
})
}
catch (failCallBack) {
return this.then(undefined, failCallBack)
}
static all (array) {
// 声明一个结果数组
let result = []
let index = 0
// 返回 Promise 对象
return new MyPromise((resolve, reject) => {
// 结果数组添加结果方法
function addData (key, value) {
result[key] = value
index++
if (index == array.length) {
// 当结果的长度和传进来的长度相等时才返回所有结果
resolve(result)
}
}
// 遍历传进来的数组
for (let i = 0; i < array.length; i++) {
// 获取数组当前的值
let current = array[i];
// 判断当前的值是否为 Promise 对象
if (current instanceof MyPromise) {
// Promise 对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值,直接添加到结果数组中
addData(i, current)
}
}
})
}
static resolve (value) {
// 是MyPromise对象直接返回的
if (value instanceof MyPromise) return value
// 不是对象,创建一个MyPromise,把 resolve(value) 返回
return new MyPromise(resolve => resolve(value))
}
static reject (reason) {
// 是MyPromise对象直接返回的
if (reason instanceof MyPromise) {
console.log(reason);
return reason
}
// 不是对象,创建一个MyPromise,把 reject(reason) 返回
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
}
function resolvePromise (promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 测试
function p1 () {
return new MyPromise((resolve, reject) => {
setTimeout(() => resolve('p1'), 2000)
})
}
MyPromise.reject(12).catch(reason => console.log(reason))
// MyPromise.reject(p1()).then(result => console.log(result))
// 结果
// 12
十四、Promise.race 方法的实现
const PENDING = 'pending' // 等待
const FULFILLED = 'fulfilled' // 成功
const REJECTED = 'rejected' // 失败
class MyPromise {
constructor(executor) {
try {
// 执行器传进来,立即执行
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// 状态,初始为pending(等待)
status = PENDING
// 保存成功的值,默认 没有
value = undefined
// 保存失败的值,默认 没有
reason = undefined
// 保存成功回调
successCallBack = []
// 保存失败回调
failCallBack = []
resolve = value => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> fulfilled(成功)
this.status = FULFILLED
// 保存成功的值
this.value = value
// 判断成功回调是否存在
// this.successCallBack && this.successCallBack(this.value)
// while (this.successCallBack.length) this.successCallBack.shift()(this.value)
while (this.successCallBack.length) this.successCallBack.shift()()
}
reject = reason => {
// 如果不是等待状态,就组织函数继续执行
if (this.status !== PENDING) return
// pending(等待) ---> rejected(失败)
this.status = REJECTED
// 保存失败的值
this.reason = reason
// console.log('this.reason', this.reason);
// 判断失败回调是否存在
// this.failCallBack && this.failCallBack(this.reason)
// while (this.failCallBack.length) this.failCallBack.shift()(this.reason)
while (this.failCallBack.length) this.failCallBack.shift()()
}
then = (successCallBack, failCallBack) => {
// 判断 successCallBack 是否存在,存在则直接调用 successCallBack,否则 value => value 重新赋值给successCallBack
successCallBack = successCallBack ? successCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
// 实现then 方法返回一个promise对象
let promise2 = new MyPromise((resolve, reject) => {
// successCallBack, failCallBack 是function
if (this.status === FULFILLED) {
// 把这部分的代码变成异步,才能正常获取promise2
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
} else {
// 状态为等待
// 将成功回调、失败回调 存储起来
this.successCallBack.push(() => {
// successCallBack()
setTimeout(() => {
try {
// 状态为成功,调用成功回调函数
let x = successCallBack(this.value)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.failCallBack.push(() => {
setTimeout(() => {
// failCallBack()
try {
// 状态为失败,调用失败回调函数
failCallBack(this.reason)
// resolve(x)
// 判断 X 的值是普通还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回结果
// 在根据promise对象返回的结果 决定调用resolve 还是reject
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
finally (callback) {
// 调用 this.then 获取当前状态
// this.then(() => { callback() }, () => { callback() })
// finally 返回的也是 Promise 对象
return this.then(value => {
// callback()
// return value
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
// callback()
// throw reason
return MyPromise.reject(callback()).then(() => { throw reason })
})
}
catch (failCallBack) {
return this.then(undefined, failCallBack)
}
static all (array) {
// 声明一个结果数组
let result = []
let index = 0
// 返回 Promise 对象
return new MyPromise((resolve, reject) => {
// 结果数组添加结果方法
function addData (key, value) {
result[key] = value
index++
if (index == array.length) {
// 当结果的长度和传进来的长度相等时才返回所有结果
resolve(result)
}
}
// 遍历传进来的数组
for (let i = 0; i < array.length; i++) {
// 获取数组当前的值
let current = array[i];
// 判断当前的值是否为 Promise 对象
if (current instanceof MyPromise) {
// Promise 对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值,直接添加到结果数组中
addData(i, current)
}
}
})
}
static resolve (value) {
// 是MyPromise对象直接返回的
if (value instanceof MyPromise) return value
// 不是对象,创建一个MyPromise,把 resolve(value) 返回
return new MyPromise(resolve => resolve(value))
}
static reject (reason) {
// 是MyPromise对象直接返回的
if (reason instanceof MyPromise) {
console.log(reason);
return reason
}
// 不是对象,创建一个MyPromise,把 reject(reason) 返回
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
static race (array) {
// 声明一个结果
let result = undefined
// 返回 Promise 对象
return new MyPromise((resolve, reject) => {
// 结果数组添加结果方法
function addData (value) {
result = value
if (result) {
// 当结果不为空的时候的就返回
resolve(result)
}
}
// 遍历传进来的数组
for (let i = 0; i < array.length; i++) {
// 获取数组当前的值
let current = array[i];
// 判断当前的值是否为 Promise 对象
if (current instanceof MyPromise) {
// Promise 对象
current.then(value => addData(value), reason => reject(reason))
} else {
// 普通值,直接添加到结果数组中
addData(current)
}
}
})
}
}
function resolvePromise (promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value), reason => reject(reason))
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// 测试
function p1 () {
return new MyPromise((resolve, reject) => {
setTimeout(() => resolve('p1'), 2000)
})
}
function p2 () {
return new MyPromise((resolve, reject) => {
// resolve('p2')
reject('p2')
})
}
MyPromise.race([p1(), p2()]).then(result => console.log(result)).catch(reason => console.log(reason))
// 结果
// p2
总结
通过手写实现 Promise,增加对 Promise 的了解。