前端基础之Promise

Promise

在我们写函数的时候通常会使用回调函数,当多个函数相互嵌套调用时就可能会产生回调地狱,为了解决这个问题,promise诞生生了,promise可以说是当前最好用的解决回调地狱的方案了。

Promise简介

promise,中文翻译为承诺,有三种状态pending,fulfilled,rejected,初始时状态为pending,成功时状态为fulfilled,失败时状态为rejected,且状态变化不可逆,只能有pending到fulfilled或pending到rejected。

Promise的使用

//调用 Promise 函数
let forget = false

let buyLv = new Promise((resolve, reject) => {
    if (forget) {
        let data = {
            name: 'Lv',
            price: 1999
        }
        resolve(data)
    } else {
        let err = {
            msg: '忘记了'
        }
        reject(err)
    }
})

buyLv.then(fulfilled => {
    console.log(fulfilled);
}).catch(rejected => {
    console.log(rejected);
})

// forget == false { msg: '忘记了' }
// forget == true  { name: 'Lv', price: 1999 }

Promise的链式调用

promise的链式调用会将上一个promise的成功结果作为下一个promise的参数then的结果为第二个promise的resolve。

let forget = true

let buyLv = new Promise((resolve, reject) => {
    if (forget) {
        let data = {
            name: 'Lv',
            price: 1999
        }
        resolve(data)
    } else {
        let err = {
            msg: '忘记了'
        }
        reject(err)
    }
})

let buyAmn = (lv) => {
    let Amn = {
        name: 'amn',
        price: 2548
    }
    let data = {
        lv: lv,
        amn: Amn
    }
    return new Promise((resolve, reject) => {
        resolve(data)
        reject(Amn)
    })
}

buyLv.then(buyAmn).then(fulfilled => {
    console.log(fulfilled);
}).catch(rejected => {
    console.log(rejected);
})

// forget == true { lv: { name: 'Lv', price: 1999 }, amn: { name: 'amn', price: 2548 } }
// forget == false { msg: '忘记了' }

Promise的实现

es5

// promise 同步
function MyPromise(excutor) {
    let self = this;
    self.state = 'pending'
    self.value = null
    self.reason = null

    function resolve(value) {
        if (self.state === 'pending') {
            self.state = "fulfilled"
            self.value = value
        }
    }

    function reject(reason) {
        if (self.state === 'pending') {
            self.state = "rejected"
            self.reason = reason
        }
    }

    try {
        excutor(resolve, reject)
    } catch (error) {
        reject(error)
    }
}

MyPromise.prototype.then = function (onFullFilled, onRejected) {
    onFullFilled = typeof onFullFilled === 'function' ? onFullFilled : function (data) { resolve(data) }
    onRejected = typeof onRejected === 'function' ? onRejected : function (err) { throw err }
    let self = this;
    if (self.state === 'fulfilled') {
        onFullFilled(self.value)
    }
    if (self.state === 'rejected') {
        onRejected(self.reason)
    }
}

let a = new MyPromise((resolve, reject) => {
    resolve(2)
})

a.then(r => {
    console.log(r);
})

// 2
//异步
function MyPromise(excutor) {
    let self = this;
    self.state = 'pending'
    self.value = null
    self.reason = null

    self.onFullFilledCallbacks = []
    self.onRejectedCallbacks = []

    function resolve(value) {
        if (self.state === 'pending') {
            self.state = "fulfilled"
            self.value = value
            self.onFullFilledCallbacks.forEach(fn => fn())
        }
    }

    function reject(reason) {
        if (self.state === 'pending') {
            self.state = "rejected"
            self.reason = reason
            self.onFullFilledCallbacks.forEach(fn => fn())
        }
    }

    try {
        excutor(resolve, reject)
    } catch (error) {
        reject(error)
    }
}

MyPromise.prototype.then = function (onFullFilled, onRejected) {
    onFullFilled = typeof onFullFilled === 'function' ? onFullFilled : function (data) { resolve(data) }
    onRejected = typeof onRejected === 'function' ? onRejected : function (err) { throw err }
    let self = this;
    if (self.state === 'fulfilled') {
        onFullFilled(self.value)
    }
    if (self.state === 'rejected') {
        onRejected(self.reason)
    }

    if (self.state === 'pending') {
        self.onFullFilledCallbacks.push(function () {
            onFullFilled(self.value)
        })
        self.onRejectedCallbacks.push(function () {
            onRejected(self.reason)
        })
    }
}

let a = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(2)
    }, 1000);
})

a.then(r => {
    console.log(r);
})

// 2s后 输出 2
// promise 链式
function MyPromise(excutor) {
    let self = this;
    self.state = 'pending'
    self.value = null
    self.reason = null

    self.onFullFilledCallbacks = []
    self.onRejectedCallbacks = []

    function resolve(value) {
        if (self.state === 'pending') {
            self.state = "fulfilled"
            self.value = value
            self.onFullFilledCallbacks.forEach(fn => fn())
        }
    }

    function reject(reason) {
        if (self.state === 'pending') {
            self.state = "rejected"
            self.reason = reason
            self.onFullFilledCallbacks.forEach(fn => fn())
        }
    }

    try {
        excutor(resolve, reject)
    } catch (error) {
        reject(error)
    }
}

MyPromise.prototype.then = function (onFullFilled, onRejected) {
    onFullFilled = typeof onFullFilled === 'function' ? onFullFilled : function (data) { resolve(data) }
    onRejected = typeof onRejected === 'function' ? onRejected : function (err) { throw err }
    let self = this;
    if (self.state === 'fulfilled') {
        return new MyPromise((resolve, reject) => {
            try {
                let x = onFullFilled(self.value)
                x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
            } catch (error) {
                reject(error)
            }
        })
    }
    if (self.state === 'rejected') {
        return new MyPromise((resolve, reject) => {
            try {
                let x = onRejected(self.value)
                x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
            } catch (error) {
                reject(error)
            }
        })
    }

    if (self.state === 'pending') {
        self.onFullFilledCallbacks.push(function () {
            return new MyPromise((resolve, reject) => {
                try {
                    let x = onFullFilled(self.value)
                    x instanceof MyPromise ? x.then(resolve, reject) : resolve(x)
                } catch (error) {
                    reject(error)
                }
            })
        })
        self.onRejectedCallbacks.push(function () {
            return new MyPromise((resolve, reject) => {
                try {
                    let x = onRejected(self.value)
                    x instanceof MyPromise ? x.then(resolve, reject) : reject(x)
                } catch (error) {
                    reject(error)
                }
            })
        })
    }
}

let a = new MyPromise((resolve, reject) => {
    resolve(2)
})

let b = (b) => {
    return new MyPromise((resolve, reject) => {
        if (b) {
            resolve(b + '8')
        } else {
            reject('b-')
        }
    })
}

let c = (c) => {
    return new MyPromise((resolve, reject) => {
        if (c) {
            resolve(c + '8ppp')
        } else {
            reject('b-')
        }
    })
}
a.then(b).then(c).then(r => {
    console.log(r);
})

// 288ppp

es6

// 同步
class MyPromise {
    constructor(executor) {
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;

        let resolve = (value) => {
            this.state = 'fulfilled'
            this.value = value
        }

        let reject = (reason) => {
            this.state = 'rejected'
            this.reason = reason
        }
        try {
            executor(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }

    then(onFullFilled, onRejected) {
        if (this.state === 'fulfilled') {
            onFullFilled(this.value)
        }

        if (this.state === 'rejected') {
            onRejected(this.reason)
        }
    }

}
// 异步
class MyPromise {
    constructor(executor) {
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;
        this.onFullFilledCallbacks = [];
        this.onRejectedCallbacks = []

        let resolve = (value) => {
            this.state = 'fulfilled'
            this.value = value
            this.onFullFilledCallbacks.forEach(fn => fn())
        }

        let reject = (reason) => {
            this.state = 'rejected'
            this.reason = reason
            this.onRejectedCallbacks.forEach(fn => fn())
        }
        try {
            executor(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }

    then(onFullFilled, onRejected) {
        if (this.state === 'fulfilled') {
            onFullFilled(this.value)
        }

        if (this.state === 'rejected') {
            onRejected(this.reason)
        }

        if (this.state === 'pending') {
            this.onFullFilledCallbacks.push(() => {
                onFullFilled(this.value)
            })
            this.onRejectedCallbacks.push(() => {
                onRejected(this.reason)
            })
        }
    }

}
// 链式
class MyPromise {
    constructor(executor) {
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;
        this.onFullFilledCallbacks = [];
        this.onRejectedCallbacks = []

        let resolve = (value) => {
            this.state = 'fulfilled'
            this.value = value
            this.onFullFilledCallbacks.forEach(fn => fn())
        }

        let reject = (reason) => {
            this.state = 'rejected'
            this.reason = reason
            this.onRejectedCallbacks.forEach(fn => fn())
        }
        try {
            executor(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }

    then(onFullFilled, onRejected) {
        onFullFilled = isFunction(onFullFilled) ? onFullFilled : data => data
        onRejected = isFunction(onRejected) ? onRejected : err => {
            throw err;
        }
        const MyPromise2 = new MyPromise((resolve, reject) => {
            let x;
            if (this.state === 'fulfilled') {
                setTimeout(() => {
                    try {
                        x = onFullFilled(this.value)
                        // resolve(x)
                        resolvePromise(MyPromise2, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                }, 0);
            }

            if (this.state === 'rejected') {
                setTimeout(() => {
                    try {
                        x = onRejected(this.reason)
                        resolvePromise(MyPromise2, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                }, 0);
            }

            if (this.state === 'pending') {
                this.onFullFilledCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            x = onFullFilled(this.value)
                            resolvePromise(MyPromise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                    }, 0);
                })
                this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            x = onRejected(this.reason)
                            resolvePromise(MyPromise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                    }, 0);

                })
            }
        })
        return MyPromise2
    }
}

function resolvePromise(MyPromise2, x, resolve, reject) {
    let called;
    if (MyPromise2 === x) {
        return reject(new TypeError('typeError'))
    }
    if ((typeof x === 'object' && x != null) || typeof x === 'function') {
        try {
            let then = x.then
            if (typeof then === 'function') {
                then.call(x, y => {
                    if (called) return
                    called = true
                    resolvePromise(MyPromise2, y, resolve, reject)
                }, r => {
                    if (called) return
                    called = true
                    reject(r)
                })
            } else {
                if (called) return
                called = true
                resolve(x)
            }
        } catch (error) {
            if (called) return
            called = true
            reject(error)
        }
    } else {
        resolve(x)
    }
}

const isFunction = (fn) => typeof fn === 'function';

let forget = true

let buyLv = new MyPromise((resolve, reject) => {
    if (forget) {
        let data = {
            name: 'Lv',
            price: 1999
        }
        resolve(data)
    } else {
        let err = {
            msg: '忘记了'
        }
        reject(err)
    }
})

let buyAmn = (lv) => {
    let Amn = {
        name: 'amn',
        price: 2548
    }
    let data = {
        lv: lv,
        amn: Amn
    }
    return new MyPromise((resolve, reject) => {
        if (forget) {
            resolve(data)
        }
        else {
            reject(Amn)
        }

    })
}


buyLv.then(buyAmn).then(fulfilled => {
    console.log(fulfilled, 'p');
}, r => {
    console.log(r, 'r');
})

// { lv: { name: 'Lv', price: 1999 }, amn: { name: 'amn', price: 2548 } } p

Promise all

promise all方法是对多个promise的判断,返回一个promise对象,当多个promise都正确的返回所有promise的resolve的值,当其中有一个错误时返回错误的promise的reject的值。

let forget = true

let p1 = new Promise((resolve, reject) => {
    resolve(1)
})
let p2 = new Promise((resolve, reject) => {
    if (forget) {
        resolve('a')
    } else (
        reject('b')
    )
})

let p3 = new Promise((resolve, reject) => {
    resolve(2)
})

Promise.all([p1, p2, p3]).then(r => {
    console.log(r);
}, e => {
    console.log(e);
})

// forget === true   [ 1, 'a', 2 ]
// forget === false  b

Promise all 实现

Promise.all2 = function (promises) {
    return new Promise(function (resolve, reject) {
        const len = promises.length;
        let count = 0;
        results = new Array(len);
        for (let i = 0; i < len; i++) {
            Promise.resolve(promises[i]).then((value) => {
                count++;
                results[i] = value;
                if (count == len) {
                    return resolve(results);
                }
            }, (reason) => {
                return reject(reason);
            })
        }
    })
}

参考视频

【全网首发:更新完】promise源码实现
ES6_Promise(3)手写一个Promise(一)
欢迎评论留言交流!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值