js 实现 promise

//三种状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

function MyPromise(f) {
    /*
   有state,有处理结果result,then的执行栈
   */
    this.state = PENDING;
    this.result = null;
    //存放onFulfilled,onRejected回调函数
    this.callbacks = []


    let onFulfilled = value => transition(this, FULFILLED, value)
    let onRejected = reason => transition(this, REJECTED, reason)

    let ignore = false;
    let resolve = value => {
        if (ignore) return;
        ignore = true;
        resolvePromise(this, value, onFulfilled, onRejected)
    }
    let reject = reason => {
        if (ignore) return;
        ignore = true;
        onRejected(reason)
    }

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

/*
Peomise.then(()=>{'onfulfilled'},()=>{'onRejected'})
then必须返回一个Promise对象
*/
MyPromise.prototype.then = function (onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
        let callback = { onFulfilled, onRejected, resolve, reject }
        if (this.state === PENDING) {
            console.log('push');
            this.callbacks.push(callback)
        } else {
            //在执行上下文栈只包含平台代码之前,不能调用onfulfillment或onRejected。
            setTimeout(() => { handleCallback(callback, this.state, this.result) }, 0)
        }
    })
}
//在当前 promise 和下一个 promise 之间进行状态传递。
const handleCallback = (callback, state, result) => {
    let { onFulfilled, onRejected, resolve, reject } = callback;
    try {
        if (state === FULFILLED) {
            isFunction(onFulfilled) ? resolve(onFulfilled(result)) : resolve(result)
        } else if (state === REJECTED) {
            isFunction(onRejected) ? resolve(onRejected(result)) : resolve(result)
        }
    } catch (error) {
        reject(error)
    }
}

//The Promise Resolution Procedure
/*
1.如果result是当前promise本身,就抛出TypeError
2.如果result是另外一个promise,就沿用他的state和result状态
3.如果result是一个thenable对象。是就先取出 then,再用 new Promise 去进入 The Promise Resolution Procedure 过程。
4.如果以上都不是,这个result成为当前promise的result
*/
const resolvePromise = (promise, result, onFulfilled, onRejected) => {
    if (result === promise) {
        let reason = new TypeError('Can not fulfill promise with itself')
        return onRejected(reason)
    }
    if (isPromise(result)) {
        return result.then(onFulfilled, onRejected)
    }
    if (isThenable(result)) {
        try {
            let then = result.then;
            if (isFunction(then)) {
                return new MyPromise(then.bind(result)).then(onFulfilled, onRejected)
            }
        } catch (error) {
            return onRejected(error)
        }
    }
    onFulfilled(result)
}

const transition = (promise, state, result) => {
    //state一旦更改为不是PENDING的状态后不可更改
    if (promise.state !== PENDING) {
        return;
    }
    promise.state = state;
    promise.result = result;
    //状态转换完成后,清空执行栈
    setTimeout(() => handleCallbacks(promise.callbacks, state, result), 0)
}

const handleCallbacks = (callbacks, state, result) => {
    while (callbacks.length) handleCallback(callbacks.shift(), state, result)
}

const isFunction = obj => typeof obj === 'function'
const isObject = obj => !!(obj && typeof obj === 'object')
const isThenable = obj => (isFunction(obj) || isObject(obj)) && 'then' in obj
const isPromise = promise => promise instanceof MyPromise



const promise1 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        console.log('promise');
        resolve()
    }, 1000);
})
promise1.then(() => {
    console.log('aaa');
    return new MyPromise(()=>{setTimeout(() => {
        console.log(3); 
    }, 1000)})
})
发布日期:
分类:js 标签:

发表评论

您的电子邮箱地址不会被公开。