Promise简单实现及应用

80 阅读15分钟

1. Promise A+规范

官⽅地址; github地址;

对照的翻译如下:

⼀个开放、健全且通⽤的 JavaScript Promise 标准。由开发者制定,供开发者参考。

⼀个 promise 表示异步操作的最终结果。与 promise 进⾏交互的主要⽅式是通过它的⽅法 then。该⽅法通过注册回调来得到这个 promise 的最终 value ,或者为什么这个 promise 不能被 fulfilled 的reason 。

该规范详细说明了 then ⽅法的⾏为,提供了⼀个可互操作的基础,因此所有符合 Promises/A+promise 实现都可以依赖该基础。尽管 Promises/A+ 组织可能偶尔会通过向后兼容的微⼩更改来修改此规范,以解决新发现的情况,但我们只有在仔细考虑、讨论和测试后才会进⾏⼤的或向后不兼容的更改。因此, 该规范应该被认为是⼗分稳定的 。

2. 简版promise

2.1 resolve和reject

let p1 = new Promise((resolve, reject) => {
    resolve('success')
    reject('fail')
})

console.log('p1', p1)

let p2 = new Promise((resolve, reject) => {
    reject('success')
    resolve('fail')
})

console.log('p2', p2)

let p3 = new Promise((resolve, reject) => {
    throw('error')
})

console.log('p3', p3)

截屏2024-05-27 14.11.12.png

这⾥说明了Promise的四个特点:

  1. 执⾏了resolve,Promise状态会变成fulfilled;
  2. 执⾏了reject,Promise状态会变成rejected;
  3. Promise状态不可逆,第⼀次成功就永久为fulfilled,第⼀次失败就永远状态为rejected;
  4. Promise中有throw的话,就相当于执⾏了reject;

2.1.1 实现resolve和reject

  1. Promise的初始状态是pending;
  2. 需要对resolve和reject绑定this:确保resolve和reject的this指向永远指向当前的MyPromise实例,防⽌随着函数执⾏环境的改变⽽改变;
class MyPromise {
    // 构造⽅法
    constructor(executor) {
        // 初始化值
        this.initValue()
        // 初始化this指向
        this.initBind()
        // 执⾏传进来的函数
        executor(this.resolve, this.reject)
    }

    initValue() {
        // 初始化值
        this.PromiseResult = null // 终值
        this.PromiseState = 'pending' // 状态
    }
    
    initBind() {
        // 初始化this
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }

    resolve(value) {
        // 如果执⾏resolve,状态变为fulfilled
        this.PromiseState = 'fulfilled'
        // 终值为传进来的值
        this.PromiseResult = value
    }

    reject(reason) {
        // 如果执⾏reject,状态变为rejected
        this.PromiseState = 'rejected'
        // 终值为传进来的reason
        this.PromiseResult = reason
    }
}

测试如下:

const test1 = new MyPromise((resolve, reject) => {
    resolve('success')
})

console.log(test1) // MyPromise { PromiseState: 'fulfilled', PromiseResult: 'success' }

const test2 = new MyPromise((resolve, reject) => {
    reject('fail')
})

console.log(test2) // MyPromise { PromiseState: 'rejected', PromiseResult:'fail' }

2.1.2 状态不可变

const test1 = new MyPromise((resolve, reject) => {
    resolve('success')
    reject('fail')
})

console.log(test1) // MyPromise { PromiseState: 'rejected', PromiseResult:'fail' }

Promise有三种状态:

  • pending:等待中,是初始状态;
  • fulfilled:成功状态;
  • rejected:失败状态;

⼀旦状态从pending变为fulfilled或者rejected,那么此Promise实例的状态就不可以改变了。

截屏2024-05-27 14.28.01.png 这步只需要:

截屏2024-05-27 14.29.29.png 也就是:

class MyPromise {
    // 构造⽅法
    constructor(executor) {
        // 初始化值
        this.initValue()
        // 初始化this指向
        this.initBind()
        // 执⾏传进来的函数
        executor(this.resolve, this.reject)
    }

    initValue() {
        // 初始化值
        this.PromiseResult = null // 终值
        this.PromiseState = 'pending' // 状态
    }
    
    initBind() {
        // 初始化this
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }

    resolve(value) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏resolve,状态变为fulfilled
        this.PromiseState = 'fulfilled'
        // 终值为传进来的值
        this.PromiseResult = value
    }

    reject(reason) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏reject,状态变为rejected
        this.PromiseState = 'rejected'
        // 终值为传进来的reason
        this.PromiseResult = reason
    }
}

结果如下:

const test1 = new MyPromise((resolve, reject) => {
    // 只以第⼀次为准
    resolve('success')
    reject('fail')
})

console.log(test1) // MyPromise { PromiseState: 'fulfilled', PromiseResult: 'success' }

2.1.3 throw

截屏2024-05-27 14.35.01.png Promise中有throw的话,就相当于执⾏了reject。这就要使⽤try catch了

class MyPromise {
    // 构造⽅法
    constructor(executor) {
        // 初始化值
        this.initValue()
        // 初始化this指向
        this.initBind()
        try {
            // 执⾏传进来的函数
            executor(this.resolve, this.reject)
        } catch (e) {
            // 捕捉到错误直接执⾏reject
            this.reject(e)
        }
    }
    
    initValue() {
        // 初始化值
        this.PromiseResult = null // 终值
        this.PromiseState = 'pending' // 状态
    }

    initBind() {
        // 初始化this
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }

    resolve(value) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏resolve,状态变为fulfilled
        this.PromiseState = 'fulfilled'
        // 终值为传进来的值
        this.PromiseResult = value
    }

    reject(reason) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏reject,状态变为rejected
        this.PromiseState = 'rejected'
        // 终值为传进来的reason
        this.PromiseResult = reason
    }
}

测试代码:

const test3 = new MyPromise((resolve, reject) => {
    throw('fail')
})

console.log(test3) // MyPromise { PromiseState: 'rejected', PromiseResult:'fail' }

2.2. then

平时业务中then的使⽤⼀般如下:

// ⻢上输出 ”success“
const p1 = new Promise((resolve, reject) => {
    resolve('success')
}).then(res => console.log(res), err => console.log(err))

// 1秒后输出 ”fail“
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('fail')
    }, 1000)
}).then(res => console.log(res), err => console.log(err))

// 链式调⽤ 输出 200
const p3 = new Promise((resolve, reject) => {
    resolve(100)
}).then(res => 2 * res, err => console.log(err))
.then(res => console.log(res), err => console.log(err))

根据上述代码可以确定:

  1. then接收两个回调,⼀个是成功回调,⼀个是失败回调;
  2. 当Promise状态为fulfilled执⾏成功回调,为rejected执⾏失败回调;
  3. 如resolve或reject在定时器⾥,则定时器结束后再执⾏then;
  4. then⽀持链式调⽤,下⼀次then执⾏受上⼀次then返回值的影响;

2.2.1 实现then

then(onFulfilled, onRejected) {
    // 接收两个回调 onFulfilled, onRejected
    // 参数校验,确保⼀定是函数
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val

    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

    if (this.PromiseState === 'fulfilled') {
        // 如果当前为成功状态,执⾏第⼀个回调
        onFulfilled(this.PromiseResult)
    } else if (this.PromiseState === 'rejected') {
        // 如果当前为失败状态,执⾏第⼆哥回调
        onRejected(this.PromiseResult)
    }
}

完整代码为:

class MyPromise {
    // 构造⽅法
    constructor(executor) {
        // 初始化值
        this.initValue()
        // 初始化this指向
        this.initBind()
        try {
            // 执⾏传进来的函数
            executor(this.resolve, this.reject)
        } catch (e) {
            // 捕捉到错误直接执⾏reject
            this.reject(e)
        }
    }
    
    initValue() {
        // 初始化值
        this.PromiseResult = null // 终值
        this.PromiseState = 'pending' // 状态
    }

    initBind() {
        // 初始化this
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }

    resolve(value) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏resolve,状态变为fulfilled
        this.PromiseState = 'fulfilled'
        // 终值为传进来的值
        this.PromiseResult = value
    }

    reject(reason) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏reject,状态变为rejected
        this.PromiseState = 'rejected'
        // 终值为传进来的reason
        this.PromiseResult = reason
    }
    
    then(onFulfilled, onRejected) {
        // 接收两个回调 onFulfilled, onRejected
        // 参数校验,确保⼀定是函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val

        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

        if (this.PromiseState === 'fulfilled') {
            // 如果当前为成功状态,执⾏第⼀个回调
            onFulfilled(this.PromiseResult)
        } else if (this.PromiseState === 'rejected') {
            // 如果当前为失败状态,执⾏第⼆哥回调
            onRejected(this.PromiseResult)
        }
    }
}

测试then的结果为:

// 输出 ”success“
const test = new MyPromise((resolve, reject) => {
    resolve('success')
}).then(res => console.log(res), err => console.log(err))

2.2.2 定时器

如何保证下述代码能够在1s后执⾏then的回调?

// 1秒后输出 ”fail“
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('fail')
    }, 1000)
}).then(res => console.log(res), err => console.log(err))

我们不能确保1秒后才执⾏then函数,但是我们可以保证1秒后再执⾏then⾥的回调

截屏2024-05-27 17.05.37.png 在这1秒时间内,我们可以先把then⾥的两个回调保存起来,然后等到1秒过后,执⾏了resolve或者reject,咱们再去判断状态,并且判断要去执⾏刚刚保存的两个回调中的哪⼀个回调。

那么问题来了,我们怎么知道当前1秒还没⾛完甚⾄还没开始⾛呢?其实很好判断,只要状态是

pending,那就证明定时器还没跑完,因为如果定时器跑完的话,那状态肯定就不是pending,⽽是fulfilled或者rejected

那是⽤什么来保存这些回调呢?建议使⽤数组,因为⼀个promise实例可能会多次then,⽤数组就⼀个⼀个保存了

class MyPromise {
    // 构造⽅法
    constructor(executor) {
        // 初始化值
        this.initValue()
        // 初始化this指向
        this.initBind()
        try {
            // 执⾏传进来的函数
            executor(this.resolve, this.reject)
        } catch (e) {
            // 捕捉到错误直接执⾏reject
            this.reject(e)
        }
    }

    initBind() {
        // 初始化this
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }

    initValue() {
        // 初始化值
        this.PromiseResult = null // 终值
        this.PromiseState = 'pending' // 状态
        this.onFulfilledCallbacks = [] // 保存成功回调
        this.onRejectedCallbacks = [] // 保存失败回调
    }

    resolve(value) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏resolve,状态变为fulfilled
        this.PromiseState = 'fulfilled'
        // 终值为传进来的值
        this.PromiseResult = value
        // 执⾏保存的成功回调
        while (this.onFulfilledCallbacks.length) {
            this.onFulfilledCallbacks.shift()(this.PromiseResult)
        }
    }

    reject(reason) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏reject,状态变为rejected
        this.PromiseState = 'rejected'
        // 终值为传进来的reason
        this.PromiseResult = reason
        // 执⾏保存的失败回调
        while (this.onRejectedCallbacks.length) {
            this.onRejectedCallbacks.shift()(this.PromiseResult)
        }
    }

    then(onFulfilled, onRejected) {
        // 接收两个回调 onFulfilled, onRejected
        // 参数校验,确保⼀定是函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val=> val
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

        if (this.PromiseState === 'fulfilled') {
            // 如果当前为成功状态,执⾏第⼀个回调
            onFulfilled(this.PromiseResult)
        } else if (this.PromiseState === 'rejected') {
            // 如果当前为失败状态,执⾏第⼆哥回调
            onRejected(this.PromiseResult)
        } else if (this.PromiseState === 'pending') {
            // 如果状态为待定状态,暂时保存两个回调
            this.onFulfilledCallbacks.push(onFulfilled.bind(this))
            this.onRejectedCallbacks.push(onRejected.bind(this))
        }
    }
}

看下是否能够实现定时器的功能:

const test2 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('success') // 1秒后输出 success
    }, 1000)
}).then(res => console.log(res), err => console.log(err))

2.2.3 链式调⽤

then⽀持链式调⽤,下⼀次then执⾏受上⼀次then返回值的影响,给⼤家举个例⼦:

// 链式调⽤ 输出 200
const p3 = new Promise((resolve, reject) => {
    resolve(100)
}).then(res => 2 * res, err => console.log(err))
.then(res => console.log(res), err => console.log(err))

// 链式调⽤ 输出300
const p4 = new Promise((resolve, reject) => {
    resolve(100)
}).then(res => new Promise((resolve, reject) => resolve(3 * res)), err => console.log(err))
.then(res => console.log(res), err => console.log(err))

根据上⽂,可以得到:

  1. then⽅法本身会返回⼀个新的Promise对象;
  2. 如果返回值是promise对象,返回值为成功,新promise就是成功;
  3. 如果返回值是promise对象,返回值为失败,新promise就是失败;
  4. 如果返回值⾮promise对象,新promise对象就是成功,值为此返回值;

then是Promise上的⽅法,那如何实现then完还能再then呢? then执⾏后返回⼀个Promise对象就⾏了,就能保证then完还能继续执⾏then; 截屏2024-05-27 17.22.47.png

then(onFulfilled, onRejected) {
    // 接收两个回调 onFulfilled, onRejected
    // 参数校验,确保⼀定是函数
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

    var thenPromise = new MyPromise((resolve, reject) => {
        const resolvePromise = cb => {
            try {
                const x = cb(this.PromiseResult)
                if (x === thenPromise && x) {
                    // 不能返回⾃身哦
                    throw new Error('不能返回⾃身。。。')
                }

                if (x instanceof MyPromise) {
                    // 如果返回值是Promise
                    // 如果返回值是promise对象,返回值为成功,新promise就是成功
                    // 如果返回值是promise对象,返回值为失败,新promise就是失败
                    // 谁知道返回的promise是失败成功?只有then知道
                    x.then(resolve, reject)
                } else {
                    // ⾮Promise就直接成功
                    resolve(x)
                }
            } catch (err) {
                // 处理报错
                reject(err)
                throw new Error(err)
            }
        }

        if (this.PromiseState === 'fulfilled') {
            // 如果当前为成功状态,执⾏第⼀个回调
            resolvePromise(onFulfilled)
        } else if (this.PromiseState === 'rejected') {
            // 如果当前为失败状态,执⾏第⼆个回调
            resolvePromise(onRejected)
        } else if (this.PromiseState === 'pending') {
            // 如果状态为待定状态,暂时保存两个回调
            this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled))
            this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected))
        }
    })

    // 返回这个包装的Promise
    return thenPromise
}

完整代码为:

class MyPromise {
    // 构造⽅法
    constructor(executor) {
        // 初始化值
        this.initValue()
        // 初始化this指向
        this.initBind()
        try {
            // 执⾏传进来的函数
            executor(this.resolve, this.reject)
        } catch (e) {
            // 捕捉到错误直接执⾏reject
            this.reject(e)
        }
    }

    initBind() {
        // 初始化this
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }

    initValue() {
        // 初始化值
        this.PromiseResult = null // 终值
        this.PromiseState = 'pending' // 状态
        this.onFulfilledCallbacks = [] // 保存成功回调
        this.onRejectedCallbacks = [] // 保存失败回调
    }

    resolve(value) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏resolve,状态变为fulfilled
        this.PromiseState = 'fulfilled'
        // 终值为传进来的值
        this.PromiseResult = value
        // 执⾏保存的成功回调
        while (this.onFulfilledCallbacks.length) {
            this.onFulfilledCallbacks.shift()(this.PromiseResult)
        }
    }

    reject(reason) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏reject,状态变为rejected
        this.PromiseState = 'rejected'
        // 终值为传进来的reason
        this.PromiseResult = reason
        // 执⾏保存的失败回调
        while (this.onRejectedCallbacks.length) {
            this.onRejectedCallbacks.shift()(this.PromiseResult)
        }
    }

    then(onFulfilled, onRejected) {
        // 接收两个回调 onFulfilled, onRejected
        // 参数校验,确保⼀定是函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

        var thenPromise = new MyPromise((resolve, reject) => {
            const resolvePromise = cb => {
                try {
                    const x = cb(this.PromiseResult)
                    if (x === thenPromise && x) {
                        // 不能返回⾃身哦
                        throw new Error('不能返回⾃身。。。')
                    }

                    if (x instanceof MyPromise) {
                        // 如果返回值是Promise
                        // 如果返回值是promise对象,返回值为成功,新promise就是成功
                        // 如果返回值是promise对象,返回值为失败,新promise就是失败
                        // 谁知道返回的promise是失败成功?只有then知道
                        x.then(resolve, reject)
                    } else {
                        // ⾮Promise就直接成功
                        resolve(x)
                    }
                } catch (err) {
                    // 处理报错
                    reject(err)
                    throw new Error(err)
                }
            }

            if (this.PromiseState === 'fulfilled') {
                // 如果当前为成功状态,执⾏第⼀个回调
                resolvePromise(onFulfilled)
            } else if (this.PromiseState === 'rejected') {
                // 如果当前为失败状态,执⾏第⼆个回调
                resolvePromise(onRejected)
            } else if (this.PromiseState === 'pending') {
                // 如果状态为待定状态,暂时保存两个回调
                this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled))
                this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected))
            }
        })

        // 返回这个包装的Promise
        return thenPromise
    }
}

测试⼀下:

const test3 = new MyPromise((resolve, reject) => {
    resolve(100) // 输出 状态:success 值: 200
}).then(res => 2 * res, err => 3 * err)
.then(res => console.log('success', res), err => console.log('fail', err))

const test4 = new MyPromise((resolve, reject) => {
    resolve(100) // 输出 状态:fail 值:200
}).then(res => new MyPromise((resolve, reject) => reject(2 * res)), err => new Promise((resolve, reject) => resolve(3 * err)))
.then(res => console.log('success', res), err => console.log('fail', err))

2.2.4.执⾏顺序

这⾥需要了解,then⽅法是微任务

const p = new Promise((resolve, reject) => {
    resolve(1)
}).then(res => console.log(res), err => console.log(err))

console.log(2)
输出顺序是 2 1

这⾥为了实现类似的功能,使⽤setTimeout代替(setTimeout为宏任务,此处主要跟在全局上的console对⽐)

const resolvePromise = cb => {
    setTimeout(() => {
        try {
            const x = cb(this.PromiseResult)
            if (x === thenPromise) {
                // 不能返回⾃身哦
                throw new Error('不能返回⾃身。。。')
            }
            if (x instanceof MyPromise) {
                // 如果返回值是Promise
                // 如果返回值是promise对象,返回值为成功,新promise就是成功
                // 如果返回值是promise对象,返回值为失败,新promise就是失败
                // 谁知道返回的promise是失败成功?只有then知道
                x.then(resolve, reject)
            } else {
                // ⾮Promise就直接成功
                resolve(x)
            }
        } catch (err) {
            // 处理报错
            reject(err)
            throw new Error(err)
        }
    })
}

⾄此,完整的代码为:

class MyPromise {
    // 构造⽅法
    constructor(executor) {
        // 初始化值
        this.initValue()
        // 初始化this指向
        this.initBind()
        try {
            // 执⾏传进来的函数
            executor(this.resolve, this.reject)
        } catch (e) {
            // 捕捉到错误直接执⾏reject
            this.reject(e)
        }
    }

    initBind() {
        // 初始化this
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }

    initValue() {
        // 初始化值
        this.PromiseResult = null // 终值
        this.PromiseState = 'pending' // 状态
        this.onFulfilledCallbacks = [] // 保存成功回调
        this.onRejectedCallbacks = [] // 保存失败回调
    }

    resolve(value) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏resolve,状态变为fulfilled
        this.PromiseState = 'fulfilled'
        // 终值为传进来的值
        this.PromiseResult = value
        // 执⾏保存的成功回调
        while (this.onFulfilledCallbacks.length) {
            this.onFulfilledCallbacks.shift()(this.PromiseResult)
        }
    }

    reject(reason) {
        // state是不可变的
        if (this.PromiseState !== 'pending') return
        // 如果执⾏reject,状态变为rejected
        this.PromiseState = 'rejected'
        // 终值为传进来的reason
        this.PromiseResult = reason
        // 执⾏保存的失败回调
        while (this.onRejectedCallbacks.length) {
            this.onRejectedCallbacks.shift()(this.PromiseResult)
        }
    }

    then(onFulfilled, onRejected) {
        // 接收两个回调 onFulfilled, onRejected
        // 参数校验,确保⼀定是函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

        var thenPromise = new MyPromise((resolve, reject) => {
            const resolvePromise = cb => {
                setTimeout(() => {
                    try {
                        const x = cb(this.PromiseResult)
                        if (x === thenPromise && x) {
                            // 不能返回⾃身哦
                            throw new Error('不能返回⾃身。。。')
                        }

                        if (x instanceof MyPromise) {
                            // 如果返回值是Promise
                            // 如果返回值是promise对象,返回值为成功,新promise就是成功
                            // 如果返回值是promise对象,返回值为失败,新promise就是失败
                            // 谁知道返回的promise是失败成功?只有then知道
                            x.then(resolve, reject)
                        } else {
                            // ⾮Promise就直接成功
                            resolve(x)
                        }
                    } catch (err) {
                        // 处理报错
                        reject(err)
                        throw new Error(err)
                    }
                })
            }

            if (this.PromiseState === 'fulfilled') {
                // 如果当前为成功状态,执⾏第⼀个回调
                resolvePromise(onFulfilled)
            } else if (this.PromiseState === 'rejected') {
                // 如果当前为失败状态,执⾏第⼆个回调
                resolvePromise(onRejected)
            } else if (this.PromiseState === 'pending') {
                // 如果状态为待定状态,暂时保存两个回调
                this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled))
                this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected))
            }
        })

        // 返回这个包装的Promise
        return thenPromise
    }
}

测试⼀下:

const test4 = new MyPromise((resolve, reject) => {
    resolve(1)
}).then(res => console.log(res), err => console.log(err))

console.log(2)

2.3. 其他⽅法

2.3.1. all

  1. 接收⼀个Promise数组,数组中如有⾮Promise项,则此项当做成功;
  2. 如果所有Promise都成功,则返回成功结果数组;
  3. 如果有⼀个Promise失败,则返回这个失败结果;
static all(promises) {
    const result = []
    let count = 0

    return new MyPromise((resolve, reject) => {
        const addData = (index, value) => {
            result[index] = value
            count++
            if (count === promises.length) resolve(result)
        }

        promises.forEach((promise, index) => {
            if (promise instanceof MyPromise) {
                promise.then(res => {
                    addData(index, res)
                }, err => reject(err))
            } else {
                addData(index, promise)
            }
        })
    })
}

2.3.2. race

  1. 接收⼀个Promise数组,数组中如有⾮Promise项,则此项当做成功;
  2. 哪个Promise最快得到结果,就返回那个结果,⽆论成功失败;
static race(promises) {
    return new MyPromise((resolve, reject) => {
        promises.forEach(promise => {
            if (promise instanceof MyPromise) {
                promise.then(res => {
                    resolve(res)
                }, err => {
                    reject(err)
                })
            } else {
                resolve(promise)
            }
        })
    })
}

2.3.3. allSettled

  1. 接收⼀个Promise数组,数组中如有⾮Promise项,则此项当做成功;
  2. 把每⼀个Promise的结果,集合成数组后返回;
static allSettled(promises) {
    return new Promise((resolve, reject) => {
        const res = []
        let count = 0
        const addData = (status, value, i) => {
            res[i] = {
                status,
                value
            }
            count++

            if (count === promises.length) {
                resolve(res)
            }
        }

        promises.forEach((promise, i) => {
            if (promise instanceof MyPromise) {
                promise.then(res => {
                    addData('fulfilled', res, i)
                }, err => {
                    addData('rejected', err, i)
                })
            } else {
                addData('fulfilled', promise, i)
            }
        })
    })
}

2.3.4. any

与all相反

  1. 接收⼀个Promise数组,数组中如有⾮Promise项,则此项当做成功;
  2. 如果有⼀个Promise成功,则返回这个成功结果;
  3. 如果所有Promise都失败,则报错;
static any(promises) {
    return new Promise((resolve, reject) => {
        let count = 0
        promises.forEach((promise) => {
            promise.then(val => {
                resolve(val)
            }, err => {
                count++
                if (count === promises.length) {
                    reject(new AggregateError('All promises were rejected'))
                }
            })
        })
    })
}

3. 使用场景

在前端开发中,Promise 通常用于处理异步操作。以下是一些常见的场景及其示例:

3.1. 网络请求

Promise 最常见的使用场景是进行网络请求,例如使用 fetch API 或其他 AJAX 库(如 Axios)进行 HTTP 请求。

示例:使用 fetch 进行网络请求

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('Error fetching data:', error);
  });

3.2. 延时操作

Promise 可以用于延时执行某些操作,例如在某些情况下需要等待一段时间再执行后续操作。

示例:使用 setTimeout 创建延时

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

delay(1000).then(() => {
  console.log('Executed after 1 second');
});

3.3. 处理用户输入

在处理用户输入时,尤其是表单提交或文件上传等操作,通常会使用 Promise 来处理异步验证或上传过程。 示例:表单提交异步验证

function validateForm(data) {
  return new Promise((resolve, reject) => {
    // 异步验证
    setTimeout(() => {
      if (data.username === 'validUser') {
        resolve('Validation successful');
      } else {
        reject('Validation failed');
      }
    }, 500);
  });
}

const formData = { username: 'testUser' };

validateForm(formData)
  .then(message => {
    console.log(message);
  })
  .catch(error => {
    console.error(error);
  });

3.4. 动画和图像加载

处理动画或图像加载等异步任务时,也可以使用 Promise

示例:等待图像加载完成

function loadImage(url) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = (error) => reject(error);
    img.src = url;
  });
}

loadImage('https://example.com/image.jpg')
  .then(img => {
    document.body.appendChild(img);
  })
  .catch(error => {
    console.error('Error loading image:', error);
  });

3.5. 链式异步操作

通过 Promise,可以链式地处理多个异步操作,按顺序执行并处理每一步的结果。

示例:链式调用多个异步操作

fetch('https://api.example.com/user')
  .then(response => response.json())
  .then(user => {
    console.log('User:', user);
    return fetch(`https://api.example.com/orders?userId=${user.id}`);
  })
  .then(response => response.json())
  .then(orders => {
    console.log('Orders:', orders);
  })
  .catch(error => {
    console.error('Error:', error);
  });

3.6. 并行处理多个异步操作

使用 Promise.allPromise.allSettled 可以并行处理多个异步操作,并在所有操作完成后执行后续逻辑。

示例:并行获取多个数据

const userPromise = fetch('https://api.example.com/user').then(res => res.json());
const ordersPromise = fetch('https://api.example.com/orders').then(res => res.json());

Promise.all([userPromise, ordersPromise])
  .then(([user, orders]) => {
    console.log('User:', user);
    console.log('Orders:', orders);
  })
  .catch(error => {
    console.error('Error:', error);
  });

3.7. 异步迭代

在需要处理多个异步任务并按顺序执行时,可以使用 Promise 配合 async/await

示例:按顺序执行异步任务

async function processTasks(tasks) {
  for (const task of tasks) {
    await task();
  }
  console.log('All tasks completed');
}

const tasks = [
  () => new Promise(resolve => setTimeout(() => { console.log('Task 1'); resolve(); }, 1000)),
  () => new Promise(resolve => setTimeout(() => { console.log('Task 2'); resolve(); }, 500)),
  () => new Promise(resolve => setTimeout(() => { console.log('Task 3'); resolve(); }, 700)),
];

processTasks(tasks);