Promise手写

(function () {
    "use strict"
    /* 核心代码 */
    function Promise(executor) {
        var self = this;

        /* 1. 必须传executor函数 */
        if(typeof executor !== 'function') throw new TypeError('Promise resolver executor is not a function');
        
        /* 2. 必须通过new创建 */
        // (new.target);//new.target存储new的那个构造函数 如果是当做普通函数执行,则值是undefined 
        if(!(self instanceof Promise)) throw new TypeError('undefined is not a Promise');
        //new的过程 
        // 1.创建一个新对象
        // 2.这个新对象内部的[[prototype]]指针被赋值为构造函数的prototype属性(构造函数的原型对象)
        // 3.构造函数内部的this指向这个新对象(this指向新对象)
        // 4.执行构造函数内部的代码(给新对象添加属性)
        // 5.如果构造函数返回非空对象,则返回该对象,否则,返回刚创建的新对象

        /* 给实例添加属性 */
        //property
        self.state = 'pending';
        self.result = undefined;
        // 为什么用数组 因为同一个实例可以多次.then() 不是链式调用 而是p.then() p.then()
        // self.onfulfilledCallbacks = [];
        // self.onrejectedCallbacks = [];
        define(self,'onfulfilledCallbacks',[]);
        define(self,'onrejectedCallbacks',[]);
        /* 改变状态的函数 */
        var change = function(state, result) {
            // 状态已经改变之后,不再进行修改了
            if(self.state !== 'pending') return;
            self.state = state;
            self.result = result;

            //异步通知集合中的方法执行
            var callbacks = state === "fulfilled"? self.onfulfilledCallbacks : self.onrejectedCallbacks;
            if(callbacks.length > 0) {
                // 用异步宏任务来模拟异步微任务 为什么这需要是异步的  异步通知集合中的方法执行
                setTimeout(function() {
                    callbacks.forEach(function(callback){
                        callback(self.result);
                    })
                })
            }
        }

        /* 立即执行executor */
        // try catch的目的 executor执行报错,状态直接改为reject 值为报错原因
        try{
            executor(
                function resolve(value){
                    change('fulfilled', value);
                },
                function reject(reason){
                    change('rejected', reason);
                }
            );
        }catch(err) {
            change('rejected', err.message);
        }

    }
    


    /* 处理THEN方法返回的新实例promise的状态和值 */
    // 第一个参数 promise是.then返回的实例p2 resolve和reject是控制p2状态和值的
    // x是onfullfilled或onrejected执行的返回结果
    // x的值决定promise的状态和值
    // onfullfilled或onrejected执行的返回结果决定promise的状态和值
    var resolvePromise = function resolvePromise(promise,x,resolve,reject) {
        if(x === promise) throw new TypeError('chaining cycle detected for promise #<promise>');
        // onfullfilled或Onrejected执行的返回值x 是一个对象或者函数
        if(x !== null && /^(object|function)$/.test(typeof x)){
            // 去访问then
            var then;
            try{
                // 获取then promise对象都有then
                then = x.then;//如果做了get劫持 有可能访问then的时候报错
            }catch(err){
                reject(err);
                return;
            }
            // 判断then方法是否为函数
            if(typeof then === 'function') {
                // 此时x可以认定为是一个promise的实例
                // 如果then是一个函数 执行then 让里面的this为x
                //检测then方法执行有没有报错
                
                var called = false; // 同时只有一个处理
                try{
                    then.call(
                        x,//这个x的成功和失败,决定了promise的成功和失败
                        // 怎么看x的成功和失败  执行x.then x成功执行onfullfilled方法 x失败执行onrejected
                        function onfulfilled(y) {
                            if(called) return;
                            called = true;
                            // 考虑到
                            //let p2 = Promise.resolve(10);
                            //let p2  = p1.then(() => {
                            //    return Promise.resolve(Promise.reject(-1)); 
                            // });
                            // 重点!!
                            resolvePromise(promise,y,resolve,reject);
                        },
                        function onrejected(r) {
                            if(called) return;
                            called = true;
                            reject(r);//x是失败的 则让promise也变成是失败的
                        }
                    );
                }catch(error){
                    if(called) return;
                    called = true;
                    //then方法执行有报错
                    reject(error);
                }
                return;
            }
        }
        // 不是promise实例 
        resolve(x);
    }

    /* 写一个方法添加属性 */
    var define = function(obj, key, value) {
        Object.defineProperty(obj, key, {
            enumerable: false,//内置属性中浅颜色的是不可枚举属性
            // 设置成不可枚举的目的:防止for..in..把共用的属性也迭代到
            writable: true,//能否重写的
            configurable: true,//能否被删除
            value: value,
        });
    }


    /* 检测是否为Promise的实例 */
    var checkInstance = function (self) {
        if(!(self instanceof Promise)){
            throw new TypeError('Method then called on incompatible reveiver #<Promise>');
        }
    }

    var proto = Promise.prototype;
    // Object.defineProperty(proto, 'then', {
    //     enumerable: false,//内置属性中浅颜色的是不可枚举属性
    //     writable: true,//能否重写的
    //     configurable: true,//能否被删除
    //     value: function() {
    //     }
    // });

    // 直接这么加是可枚举的
    // proto.catch = function() {}

    /* 原型对象 */
    define(proto,Symbol.toStringTag, "Promise")
    define(proto,'then', function then(onfulfilled, onrejected) {
        // 为什么需要判断是否为promise实例呢 then只能通过实例调用 不能通过Promise.prototypr.then()调用
        // Promise.then应该是异步微任务
        checkInstance(this)
        var self = this;
        var promise;

        /* 实现THEN的穿透机制 */
        // 判断onfullfilled和onrejected有没有传
        if(typeof onfulfilled !== 'function') {
            onfulfilled = function(value) {
                return value;
            }
        }
        if(typeof onrejected !== 'function') {
            onrejected = function(reason) {
                throw reason;
            }
        }

        /* 实现THEN链机制 */
        //promise的状态最终由resolve和reject决定,返回的值由onfulfilled和onrejected的返回值决定,如果它俩执行的时候报错,promise的状态为reject
        promise = new Promise(function(resolve, reject) {
            switch (self.state) {
                case 'fulfilled':
                    // queueMicrotask(()=>{})//创建异步微任务
                    // 用异步宏任务来模拟
                    setTimeout(function(){
                        try{
                            var x = onfulfilled(self.result);//x是返回值
                            //promise是返回的新实例 resolve reject改变新实例的状态
                            resolvePromise(promise, x, resolve, reject);
                        }catch(err) {
                            reject(err);
                        }
                    });
                    break;
                case 'rejected':
                    setTimeout(function(){
                        try{
                            var x = onrejected(self.result);
                            resolvePromise(promise, x, resolve, reject);
                        }catch(err) {
                            reject(err);
                        }
                    })
                    break;
                default: 
                // self.onfulfilledCallbacks.push(onrejected);
                // self.onrejectedCallbacks.push(onrejected);
                // 往集合中放一个匿名函数 结果是一样的 但是可以实现 onfullfilled执行放到当前上下中了?
                //要在当前上下文执行才能拿到resolve和reject push了一个function
                self.onfulfilledCallbacks.push(function(value){
                        try{
                            var x = onfulfilled(value);
                            resolvePromise(promise, x, resolve, reject);
                        }catch(err){
                            reject(err);
                        }
                    });
                    self.onrejectedCallbacks.push(function(value){
                        try{
                            var x = onrejected(value);
                            resolvePromise(promise, x, resolve, reject);
                        }catch(err){
                            reject(err);
                        }
                    });
                // 把方法存储起来,在修改状态的时候,去通知执行
            }
        });
        return promise;
    });
    define(proto,'catch', function catchMy(onrejected) {
        checkInstance(this)
        var self = this;
        return self.then(null,onrejected);
    });

    /* 静态私有属性方法 */
    define(Promise,'resolve', function resolve(value) {
        return new Promise(function(resolve) {
            resolve(value);
        });
    });
    define(Promise,'reject', function reject(reason) {
        return new Promise(function(_,reject) {
            reject(reason);
        });
    })

//     let p1 = new Promise((resolve, reject)=>{
//         resolve(10);
//     });
// /*     let p2 = p1.then((value)=>{
//         console.log('成功', value);
//         return new Promise((_, reject)=>{
//             reject(-1);
//         })
//     }, (reason)=>{
//         console.log('失败', reason);
//     }); */
//     let p2 = p1.then(null);
//     /* 
//     value => value  p2状态为成功 
//     reason => throw reason  p2状态为失败
//     */
//     p2.then((value)=>{
//         console.log('成功', value);
//     }, (reason)=>{
//         console.log('失败', reason);
//     });


    /* 暴露API */
    if(typeof window !== undefined) window.Promise = Promise;
    if(typeof module === 'object' && typeof module.exports === 'object') module.exports = Promise;
})();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是手写Promise实现: ```javascript class MyPromise { constructor(executor) { this.status = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.status === 'pending') { this.status = 'fulfilled'; this.value = value; this.onResolvedCallbacks.forEach(fn => fn()); } }; const reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value; onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }; const promise2 = new MyPromise((resolve, reject) => { if (this.status === 'fulfilled') { setTimeout(() => { try { const x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.status === 'rejected') { setTimeout(() => { try { const x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.status === 'pending') { this.onResolvedCallbacks.push(() => { setTimeout(() => { try { const x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } }); return promise2; } catch(onRejected) { return this.then(null, onRejected); } } function resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { return reject(new TypeError('Circular reference')); } if (x instanceof MyPromise) { x.then(value => { resolvePromise(promise2, value, resolve, reject); }, reject); } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) { let then; try { then = x.then; if (typeof then === 'function') { then.call(x, value => { resolvePromise(promise2, value, resolve, reject); }, reason => { reject(reason); }); } else { resolve(x); } } catch (error) { reject(error); } } else { resolve(x); } } ``` 以上是一个基本的Promise实现,它具有Promise的基本特性,包括状态管理、异步操作、链式调用、错误处理等。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [超详细!一次性搞懂手写Promise全过程](https://blog.csdn.net/qq_41852789/article/details/128453341)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Promise学习-手写一个promise](https://blog.csdn.net/qq_42161935/article/details/120672260)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值