Promise学习记录(手写Promise)

js异步编程,详解Promise、Generator、async、await(含手动实现promise)
从零开始手写Promise

简单版本

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

function CustomPromise(executor) {
    
    
    let _this = this
    this.state = PENDING; //状态
    this.value = undefined; //成功结果
    this.reason = undefined; //失败原因
    this.onFulfilled = [];//成功的回调
    this.onRejected = []; //失败的回调

    function resolve(value) {
    
    
        if(_this.state === PENDING){
    
    
            _this.state = FULFILLED
            _this.value = value
            _this.onFulfilled.forEach(fn => fn(value))
        }
    }
    function reject(reason) {
    
    
        if(_this.state === PENDING){
    
    
            _this.state = REJECTED
            _this.reason = reason
            _this.onRejected.forEach(fn => fn(reason))
        }
    }
    try {
    
    
        executor(resolve, reject)
    } catch (e) {
    
    
        reject(e)
    }
}

CustomPromise.prototype.then = function (onFulfilled, onRejected) {
    
    
    switch (this.state) {
    
    
        case FULFILLED:
            typeof onFulfilled === 'function' && onFulfilled(this.value)
            break
        case REJECTED:
            typeof onRejected === 'function' && onRejected(this.reason)
            break
        case PENDING:
            typeof onFulfilled === 'function' && this.onFulfilled.push(onFulfilled)
            typeof onRejected === 'function' && this.onRejected.push(onRejected)
    }
};

module.exports = CustomPromise

进阶版(链式调用then)

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

function CustomPromise(executor) {
    
    
    let _this = this
    this.state = PENDING; //状态
    this.value = undefined; //成功结果
    this.reason = undefined; //失败原因
    this.onFulfilled = [];//成功的回调
    this.onRejected = []; //失败的回调

    function resolve(value) {
    
    
        if (_this.state === PENDING) {
    
    
            _this.state = FULFILLED
            _this.value = value
            _this.onFulfilled.forEach(fn => fn(value))
        }
    }

    function reject(reason) {
    
    
        if (_this.state === PENDING) {
    
    
            _this.state = REJECTED
            _this.reason = reason
            _this.onRejected.forEach(fn => fn(reason))
        }
    }

    try {
    
    
        executor(resolve, reject)
    } catch (e) {
    
    
        reject(e)
    }
}

CustomPromise.prototype.then = function (onFulfilled, onRejected) {
    
    
    let _this = this
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
    onRejected = typeof onRejected === 'function' ? onRejected : reason => {
    
    
        throw reason
    }
    let promise2 = new CustomPromise((resolve, reject) => {
    
    
        try {
    
    
            let x;
            switch (_this.state) {
    
    
                case FULFILLED:
                    x = onFulfilled(_this.value)
                    resolvePromise(promise2, x, resolve, reject)
                    break
                case REJECTED:
                    x = onRejected(_this.reason)
                    resolvePromise(promise2, x, resolve, reject)
                    break
                case PENDING:
                    this.onFulfilled.push(() => {
    
    
                        x = onFulfilled(_this.value)
                        resolvePromise(promise2, x, resolve, reject)
                    })
                    this.onRejected.push(() => {
    
    
                        x = onRejected(_this.reason)
                        resolvePromise(promise2, x, resolve, reject)
                    })
            }
        } catch (e) {
    
    
            reject(e)
        }
    })
    return promise2
};

function resolvePromise(promise2, x, resolve, reject) {
    
    
    if (promise2 === x) {
    
    //防止死循环
        reject(new TypeError('Chaining cycle'))
    }
    if (x && typeof x === 'object' || typeof x === 'function') {
    
    
        let used;
        try {
    
    
            let then = x.then
            if (typeof then === 'function') {
    
    //验证x.then是否是thenable的
                then.call(x, (y) => {
    
    
                    if (used) return;
                    used = true
                    resolvePromise(promise2, y, resolve, reject)
                }, (r) => {
    
    
                    if (used) return;
                    used = true
                    reject(r)
                })
            } else {
    
    
                if (used) return;
                used = true
                resolve(x)
            }
        } catch (e) {
    
    
            if (used) return;
            used = true
            reject(e)
        }
    } else {
    
    //普通值继续向下传递
        resolve(x)
    }
}

module.exports = CustomPromise

猜你喜欢

转载自blog.csdn.net/qq_40026668/article/details/113868823