Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

手写一个promise #25

Open
wuxianqiang opened this issue Jan 7, 2018 · 0 comments
Open

手写一个promise #25

wuxianqiang opened this issue Jan 7, 2018 · 0 comments
Labels

Comments

@wuxianqiang
Copy link
Owner

wuxianqiang commented Jan 7, 2018

先了解一下Promise,Promise是通过构造函数的方式来定义,Promise有三种状态,Promise支持then方法,那么知道了这些,就简单的实现一下。

function Promise(executer) {
    // 默认的状态
    this.status = "pending";
    // 成功时的参数
    this.value = undefined;
    // 失败时的参数
    this.reason = undefined;

    let resolve = value => {
        // 用箭头函数保留this指向
        if (this.status === "pending") {
            this.status = "resolved"
            this.value = value;
        }
    }
    let reject = reason => {
        if (this.status === "pending") {
            this.status = "rejected";
            this.reason = reason;
        }
    }

    try {
        // 代码没错时执行
        executer(resolve, reject);
    } catch (error) {
        // 代码有错时执行
        reject(error);
    }
}
Promise.prototype.then = function (onFulfilled, onRejected) {
    if (this.status === "resolved") {
        // 成功时的回调
        onFulfilled(this.value)
    }
    if (this.status === "rejected") {
        // 失败时的回调
        onRejected(this.reason);
    }
}

下面比较完整的写法

function Promise(executer) {
    this.status = "pending";
    this.value = undefined;
    this.reason = undefined;
    this.resolveCallbacks = [];
    this.rejectCallbacks = [];
    let resolve = (value) => {
        if (this.status == "pending") {
            this.value = value;
            this.status = "resolved";
            this.resolveCallbacks.forEach(item => item(this.value))
        }
    };
    let reject = (reason) => {
        if (this.status == "pending") {
            this.reason = reason;
            this.status = "rejected";
            this.rejectCallbacks.forEach(item => item(this.reason))
        }
    };
    try {
        executer(resolve, reject)
    } catch (e) {
        reject(e)
    }
}
Promise.prototype.then = function (onFulfilled, onREjected) {
    if (this.status == "resolved") {
        return new Promise((resolve, reject) => {
            let val = onFulfilled(this.value);
            if (val instanceof Promise) {
                val.then(resolve, reject)
            } else {
                resolve(val);
            }
        })
    }
    if (this.status == "rejected") {
        return new Promise((resolve, reject) => {
            let val = onREjected(this.value);
            if (val instanceof Promise) {
                val.then(resolve, reject)
            } else {
                resolve(val);
            }
        })
    }
    if (this.status == "pending") {
        return new Promise((resolve, reject) => {
            this.resolveCallbacks.push(() => {
                let val = onFulfilled(this.value);
                if (val instanceof Promise) {
                    val.then(resolve, reject)
                } else {
                    resolve(val);
                }
            });
            this.rejectCallbacks.push(() => {
                let val = onREjected(this.value);
                if (val instanceof Promise) {
                    val.then(resolve, reject)
                } else {
                    resolve(val);
                }
            });
        })
    }
};
module.exports = Promise;
@wuxianqiang wuxianqiang changed the title 写一个promise 手写一个promise Jan 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant