从零开始一个完整的promise(附源码)
作者:互联网
实现过程详细步骤,文档传送门
源码:
// 先定义三个状态变量
const PENDING = 'pending'
const REJECTED = 'rejected'
const FULFILLED = 'fulfilled'
class MyPromise {
state = PENDING
value = '' // 向后传的value值
callbacks = [] // 回调队列
constructor(fn) {
if (typeof fn !== "function") {
throw new Error('参数必须是函数')
}
fn(this._resolve.bind(this), this._reject.bind(this))
}
static resolve(data) {
return new MyPromise(resolve => {
resolve(data)
})
}
static reject(data) {
return new MyPromise((resolve, reject) => {
reject(data)
})
}
static all(promiseArr) {
if (!Array.isArray(promiseArr)) {
throw new Error('参数必须是数组')
}
return new MyPromise((resolve, reject) => {
const result = []
const Arrlength = promiseArr.length
let tempItem
let resolveNums = 0 //记录fulfilled实例的个数
for (let i = 0; i < Arrlength; i++) {
tempItem = promiseArr[i]
if (!(tempItem instanceof MyPromise)) {
tempItem = MyPromise.resolve(tempItem)
}
tempItem.then((data) => {
resolveNums++
result[i] = data
// 全部都变为fulfilled,返回
if (resolveNums === Arrlength) {
resolve(result)
}
}, (data) => {
reject(data)
})
}
})
}
static race(promiseArr) {
if (!Array.isArray(promiseArr)) {
throw new Error('参数必须是数组')
}
return new MyPromise((resolve, reject) => {
const Arrlength = promiseArr.length
let tempItem
for (let i = 0; i < Arrlength; i++) {
tempItem = promiseArr[i]
if (!(tempItem instanceof MyPromise)) {
tempItem = MyPromise.resolve(tempItem)
}
tempItem.then((data) => {
resolve(data)
}, (data) => {
reject(data)
})
}
})
}
static any(promiseArr) {
if (!Array.isArray(promiseArr)) {
throw new Error('参数必须是数组')
}
return new MyPromise((resolve, reject) => {
const result = []
const Arrlength = promiseArr.length
let tempItem
let rejectedNums = 0 //记录rejected实例的个数
for (let i = 0; i < Arrlength; i++) {
tempItem = promiseArr[i]
if (!(tempItem instanceof MyPromise)) {
tempItem = MyPromise.resolve(tempItem)
}
tempItem.then(data => {
resolve(data)
}, data => {
result[i] = data
if (++rejectedNums === Arrlength) {
reject(result)
}
})
}
})
}
// 捕获前边未处理的reject。
catch(onRejected) {
return this.then(null, onRejected)
}
// 无论前边promise是何种状态,都会执行的方法
finally(fn) {
return this.then(fn, fn)
}
then(onFulfilled, onRejected) {
const _this = this; //_this指向前一个promise对象
return new MyPromise((resolve, reject) => {
_this._handle({
onFulfilled,
onRejected,
resolve,
reject
})
})
}
_resolve(value) {
if (this.state !== PENDING) {
return
}
this.state = FULFILLED //修改状态
this.value = value // 赋值,用于向后传递
this.callbacks.forEach(cb => this._handle(cb)) //回调then中的注册函数
}
_reject(error) {
if (this.state !== PENDING) {
return
}
this.state = REJECTED //修改状态
this.value = error // 赋值,用于向后传递
this.callbacks.forEach(cb => this._handle(cb)) //回调then中的注册函数
}
_handle(callback) {
// prnding状态时,注册函数入栈
if (this.state === PENDING) {
this.callbacks.push(callback)
return
}
// 按需获取then中注册的回调函数
const cb = this.state === FULFILLED ? callback.onFulfilled : callback.onRejected
// 改变then返回的promise的状态,持续回调后续的then
const cb_changeState = this.state === FULFILLED ? callback.resolve : callback.reject
let ret
if (cb) {
ret = cb(this.value) //计算继续向后传递的值
// 返回一个promise
if (ret instanceof MyPromise) {
ret.then((data) => {
callback.resolve(data)
}, (err) => {
callback.reject(err)
})
} else {
callback.resolve(ret)
}
} else {
cb_changeState(this.value) //then里没有回调函数,把当前value继续向下传递
}
}
}
标签:resolve,tempItem,MyPromise,从零开始,promise,promiseArr,reject,data,源码 来源: https://blog.csdn.net/u013910340/article/details/118391385