Skip to content

关于promise/A+的几个疑问? #16

@zhufengnodejs

Description

@zhufengnodejs

一种实现代码

function Promise(executor) {
    let self = this;
    self.status = 'pending';
    self.value = undefined;
    self.onResolvedCallbacks = [];
    self.onRejectedCallbacks = [];

    function resolve(value) {
        if (value instanceof Promise)
            return value.then(resolve, reject);

        setTimeout(function () {
            if (self.status == 'pending') {
                self.status = 'fulfilled';
                self.value = value;
                self.onResolvedCallbacks.forEach(item => item(value));
            }
        });
    }

    function reject(reason) {
        setTimeout(function () {
            if (self.status == 'pending') {
                self.status = 'rejected';
                self.value = reason;
                self.onRejectedCallbacks.forEach(item => item(reason));
            }
        });
    }

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

function resolvePromise(promise2, x, resolve, reject) {
    if (x === promise2)
        return reject(new TypeError('死循环'));
    let then, called = false;
    if (x instanceof Promise) {
        if (x.status == "pending") {
            x.then(function (y) {
                resolvePromise(promise2, y, resolve, reject);
            }, reject);
        } else {
            x.then(resolve, reject);
        }
    } else if (x != null && ((typeof x == 'object' || typeof x == 'function'))) {
        try {
            then = x.then;
            if(typeof then == 'function'){
                then.call(x, function (y) {
                    if (called) return;
                    called = true;
                    resolvePromise(promise2, y, resolve, reject);
                }, function (y) {
                    if (called) return;
                    called = true;
                    reject(y);
                });
            }else{
                resolve(x);
            }
        } catch (e) {
            if (called) return;
            called = true;
            reject(e);
        }
    } else {
        resolve(x);
    }
}

Promise.prototype.then = function (onFulfilled, onRejected) {
    let self = this;
    var promise2;
    onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : value => value;
    onRejected = typeof onRejected == 'function' ? onRejected : reason => {
        throw reason
    };
    if (self.status == 'fulfilled') {
        return promise2 = new Promise(function (resolve, reject) {
            setTimeout(function() {
                try {
                    let x = onFulfilled(self.value);
                    resolvePromise(promise2, x, resolve, reject)
                } catch (e) {
                    reject(e);
                }
            });
        });
    }
    if (self.status == 'rejected') {
        return promise2 = new Promise(function (resolve, reject) {
            setTimeout(function() {
                try {
                    let x = onRejected(self.value);
                    resolvePromise(promise2, x, resolve, reject)
                } catch (e) {
                    reject(e);
                }
            });
        });
    }
    if (self.status == 'pending') {
        return promise2 = new Promise(function (resolve, reject) {
            self.onResolvedCallbacks.push(function () {
                try {
                    let x = onFulfilled(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            });
            self.onRejectedCallbacks.push(function () {
                try {
                    let x = onRejected(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            });
        });
    }
}

Promise.prototype.catch = function (onRejected) {
    return this.then(null, onRejected)
}

Promise.deferred = Promise.defer = function () {
    var dfd = {}
    dfd.promise = new Promise(function (resolve, reject) {
        dfd.resolve = resolve
        dfd.reject = reject
    })
    return dfd
}

module.exports = Promise;

我有以下问题

  1. x === promise2什么时候会出现?为什么会循环依赖?
  2. 添加called是为了防止多次then,什么时候出现这种情况?
  3. 为什么要在处理函数里用setTimeout?
  4. typeof x == 'function' 什么时候x会是一个对象

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions