写个promise

130 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第28天,点击查看活动详情

大家好,我是大帅子,写个promise,下面我们直接开始吧,


// 解析链式调用 function resolvePromise(x, promise2, resolve, reject) { if (x === promise2) { return reject(new TypeError('循环引用')); } let called; // x 是一个函数或者是一个对象,就有可能是一个 Promise if (x !== null && (typeof x === 'function' || typeof x === 'object')) { try { let then = x.then; if (typeof then === 'function') {

            then.call(
                x,
                function(y) {
                    // called 的作用是,只能调 resolve 或 reject 不能调用 2 次
                    // 没调过
                    // #1
                    if (called) return;
                    called = true;
                    // y 可能还是一个 Promise,那就递归,直到是一个常量为止
                    // resolve(y);
                    resolvePromise(y, promise2, resolve, reject);
                },
                function(r) {
                    if (called) return;
                    called = true;
                    reject(r);
                }
            );
        } else {
            // x => { then: 123 }
            // if (called) return;
            // called = true;
            resolve(x);
        }
    } catch (e) {
        // #3
        if (called) return;
        called = true;
        
        // x.then 发生了异常
        reject(e);
    }
} else {
    // 普通值的情况直接 resolve 即可
    resolve(x);
}

}

// executor 执行出错应该进行错误捕获 function Promise(executor) { let self = this; self.value = undefined; self.reason = undefined; self.onResolvedCallbacks = []; self.onRejectedCallbacks = [];

self.status = 'pending';

function resolve(value) {
    if (self.status === 'pending') {
        self.value = value;
        self.status = 'resolved';

        self.onResolvedCallbacks.forEach(function(fn) {
            fn();
        });
    }
}

function reject(reason) {
    if (self.status === 'pending') {
        self.reason = reason;
        self.status = 'rejected';

        self.onRejectedCallbacks.forEach(function(fn) {
            fn();
        });
    }
}
try {
    executor(resolve, reject);
} catch (e) {
    reject(e);
}

}

Promise.prototype.then = function(onFulFilled, onRejected) { onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : function(data) { return data; };

onRejected = typeof onRejected === 'function' ? onRejected : function(err) {
    throw err;
};
let self = this;

let promise2 = new Promise(function(resolve, reject) {
    if (self.status === 'resolved') {
        // 调用传递过来的参数,并传递 resolve 的结果
        // 如果 x 是普通值,就让这个返回的 Promise 变成成功态
        setTimeout(() => {
            try {
                let x = onFulFilled(self.value);
                // setTimeout 包裹的目的是为了在这里拿到 promise2
                resolvePromise(x, promise2, resolve, reject);
            } catch (e) {
                reject(e);
            }
        }, 0);
    }

    if (self.status === 'rejected') {
        setTimeout(() => {
            try {
                let x = onRejected(self.reason);
                resolvePromise(x, promise2, resolve, reject);
            } catch (e) {
                reject(e);
            }
        }, 0);
    }

    // executor 中有异步操作,then 时处于等待
    if (self.status === 'pending') {
        self.onResolvedCallbacks.push(function() {
            // 这里不用 setTimeout 也行,因为走到这里的代码外部是通过异步调用的 resolve
            setTimeout(() => {
                try {
                    let x = onFulFilled(self.value);
                    resolvePromise(x, promise2, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            }, 0);
        });

        self.onRejectedCallbacks.push(function() {
            setTimeout(() => {
                try {
                    let x = onRejected(self.reason);
                    resolvePromise(x, promise2, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            }, 0);
        });
    }
});

return promise2;

};

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

module.exports = Promise;

// promises-aplus-tests promise7.js


好了,这边已经给大家介绍到这里,以上是我自己的理解,希望可以帮到大家, 欢迎留言我这边一定会第一时间给大家解答,喜欢的可以点赞收藏,
🐣---->🦅        还需努力!大家一起进步!!!