六、手撕(自定义)Promise
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一,本文详细介绍了如何手写一个Promise,即手撕Promise,主要封装了Promise的then、catch、resolve、reject、all、race方法
1. 初始化结构搭建
/*
自定义 Promise
*/
/*
Promise 构造函数
excutor: 内部同步执行的函数 (resolve, reject) => {}
*/
function Promise(executor) {
}
/* then方法
为 promise 指定成功/失败的回调函数
函数的返回值是一个新的 promise 对象
*/
Promise.prototype.then = function (onResolved, onRejected) {
}
/*
为 promise 指定失败的回调函数
是 then(undefined, onRejected)的语法糖
*/
Promise.prototype.catch = function (onRejected) {
}
/*
返回一个指定了成功 value 的 promise 对象
*/
Promise.resolve = function (value) {
}
/*
返回一个指定了失败 reason 的 promise 对象
*/
Promise.reject = function (reason) {
}
/*
返回一个 promise, 只有 promises 中所有 promise 都成功时, 才最终成功, 只要有一个失败就直接失败
*/
Promise.all = function (promises) {
}
/*
返回一个 promise, 一旦某个 promise 解决或拒绝, 返回的 promise 就会解决或拒绝。
*/
Promise.race = function (promises) {
}
2. Promise 构造函数的实现
function Promise(executor) {
// 添加属性
this.PromiseState = 'pending'
this.PromiseResult = null
// 声明属性
this.callbacks = []
// 保存实例对象的this
const self = this
/*
异步处理成功后应该调用的函数
value: 将交给 onResolve()的成功数据
*/
function resolve(data) {
// 判断状态 保证状态只更改一次
if (self.PromiseState !== 'pending') return
// 1.修改对象的状态(PromiseState)
self.PromiseState = 'fulfilled'
// 2.设置对象结果值(PromiseResult)
self.PromiseResult = data
// 异步调用成功的回调
setTimeout(() => {
self.callbacks.forEach(i => i.onResolved(data))
});
}
/*
异步处理失败后应该调用的函数
reason: 将交给 onRejected()的失败数据
*/
function reject(data) {
if (self.PromiseState !== 'pending') return
// 1.修改对象的状态(PromiseState)
self.PromiseState = 'rejected'
// 2.设置对象结果值(PromiseResult)
self.PromiseResult = data
// 异步调用失败的回调
setTimeout(() => {
self.callbacks.forEach(i => i.onRejected(data))
});
}
// 抛出错误改变状态
try {
// 同步调用【执行器函数】
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
2. promise.then()的实现
/* then方法
为 promise 指定成功/失败的回调函数
函数的返回值是一个新的 promise 对象
*/
Promise.prototype.then = function (onResolved, onRejected) {
const self = this
// 判断回调函数
// 如果 onResolved/onRejected 不是函数, 可它指定一个默认的函数
if (typeof onRejected !== 'function') {
onRejected = (reason) => {
throw reason
}
}
if (typeof onResolved !== 'function') {
onResolved = value => value
}
return new Promise((resolve, reject) => {
/*
专门抽取的用来处理 promise 成功/失败结果的函数
callback: 成功/失败的回调函数
*/
function callback(onEvent) {
try {
let result = onEvent(self.PromiseResult)
// 判断
if (result instanceof Promise) {
// 如果返回结果是Promise类型的对象,PromiseState和PromiseResult由改对象决定
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 返回的结果为非Promise对象,返回PromiseState为fufilled的Promise对象
// 结果的状态为成功
resolve(result)
}
} catch (error) {
reject(error)
}
}
// 调用成功回调函数
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
});
}
// 调用失败回调
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
});
}
// 异步
if (this.PromiseState === 'pending') {
// 保存异步执行的回调函数
this.callbacks.push({
onResolved: function () {
callback(onResolved)
},
onRejected: function () {
callback(onRejected)
}
})
}
})
}
3. promise.catch()的实现
// 添加catch方法 返回Promise对象
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
4. Promise.resolve()的实现
// 添加resolve方法
Promise.resolve = function (data) {
return new Promise((resolve, reject) => {
try {
// 判断
if (data instanceof Promise) {
// 如果返回结果是Promise类型的对象,PromiseState和PromiseResult和该对象一致
data.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 返回的结果为非Promise对象,返回PromiseState为fufilled的Promise对象
// 结果的状态为成功
resolve(data)
}
} catch (error) {
reject(error)
}
})
}
5. Promise.reject()的实现
// 添加reject方法
Promise.reject = function (data) {
return new Promise((resolve, reject) => {
reject(data)
})
}
6. Promise.all()的实现
// 添加all方法
// 返回一个新的 promise
// 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败
// 如果都成功,返回的结果PromiseResult是三个成功结果形成的数组
// 如果存在失败,直接失败,就返回的结果PromiseResult是第一个失败结果
Promise.all = function (promiseArr) {
return new Promise((resolve, reject) => {
let result = []
let count = 0
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(
v => {
// 按Promise对象数组的顺序放置对应结果
result[i] = v
count++
// 当全部成功时,返回的Promise对象成功,结果为成功数组
if (count === promiseArr.length) {
resolve(result)
}
},
r => {
// 当有一个失败,则返回该失败的Promise对象
reject(r)
}
)
}
})
}
7. Promise.race()的实现
// 添加race方法
// 返回一个新的 promise, {{第一个完成的}} promise 的结果状态就是最终的结果状态
Promise.race = function (promiseArr) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(
v => {
resolve(v)
},
r => {
reject(r)
})
}
})
}
8. ES6的class实现Promise
class Promise {
// 构造方法
constructor(executor) {
// 添加属性
this.PromiseState = 'pending'
this.PromiseResult = null
// 声明属性
this.callbacks = []
// 保存实例对象的this
const self = this
function resolve(data) {
// 判断状态 保证状态只更改一次
if (self.PromiseState !== 'pending') return
// 1.修改对象的状态(PromiseState)
self.PromiseState = 'fulfilled'
// 2.设置对象结果值(PromiseResult)
self.PromiseResult = data
// 异步调用成功的回调
setTimeout(() => {
self.callbacks.forEach(i => i.onResolved(data))
});
}
function reject(data) {
if (self.PromiseState !== 'pending') return
// 1.修改对象的状态(PromiseState)
self.PromiseState = 'rejected'
// 2.设置对象结果值(PromiseResult)
self.PromiseResult = data
// 异步调用失败的回调
setTimeout(() => {
self.callbacks.forEach(i => i.onRejected(data))
});
}
try {
// 同步调用【执行器函数】
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// then方法
then(onResolved, onRejected) {
const self = this
// 判断回调函数
if (typeof onRejected !== 'function') {
onRejected = (reason) => {
throw reason
}
}
if (typeof onResolved !== 'function') {
onResolved = value => value
}
return new Promise((resolve, reject) => {
// 封装函数
function callback(onEvent) {
try {
let result = onEvent(self.PromiseResult)
// 判断
if (result instanceof Promise) {
// 如果返回结果是Promise类型的对象,PromiseState和PromiseResult由改对象决定
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 返回的结果为非Promise对象,返回PromiseState为fufilled的Promise对象
// 结果的状态为成功
resolve(result)
}
} catch (error) {
reject(error)
}
}
// 调用回调函数
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
});
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
});
}
// 异步
if (this.PromiseState === 'pending') {
// 保存回调函数
this.callbacks.push({
onResolved: function () {
callback(onResolved)
},
onRejected: function () {
callback(onRejected)
}
})
}
})
}
// catch方法
catch (onRejected) {
return this.then(undefined, onRejected)
}
// resolve方法
static resolve(data) {
return new Promise((resolve, reject) => {
try {
// 判断
if (data instanceof Promise) {
// 如果返回结果是Promise类型的对象,PromiseState和PromiseResult由改对象决定
data.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
// 返回的结果为非Promise对象,返回PromiseState为fufilled的Promise对象
// 结果的状态为成功
resolve(data)
}
} catch (error) {
reject(error)
}
})
}
// reject方法
static reject(data) {
return new Promise((resolve, reject) => {
reject(data)
})
}
// 添加all方法
// 返回一个新的 promise
// 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败
// 如果都成功,返回的结果PromiseResult是三个成功结果形成的数组
// 如果存在失败,直接失败,就返回的结果PromiseResult是第一个失败结果
static all(promiseArr) {
return new Promise((resolve, reject) => {
let result = []
let count = 0
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(
v => {
result[i] = v
count++
if (count === promiseArr.length) {
resolve(result)
}
},
r => {
reject(r)
}
)
}
})
}
// race方法
// 返回一个新的 promise, {{第一个完成的}} promise 的结果状态就是最终的结果状态
static race(promiseArr) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(
v => {
resolve(v)
},
r => {
reject(r)
})
}
})
}
}