尝试去实现一个Promise


function resolve_promise_value(promise,value) {//PromiseA+的实现
    var then;
    /*
        ret false 说明没有执行promise._resolve里的函数
        ret true 说明执行了promise._resolve里的函数
        ret error 说明执行promise._resolve里的函数过程中出现错误
    */
    var ret = false;

    /*
        resolve(promise)和执行resolve状态时的回调函数后返回的结果都需要执行resolve(promise,value)
    */
    if (value === promise) {//传进来的对象不能等于当前的Promise对象
        promise.reject(new TypeError('TypeError'));
    } else if (value && value instanceof Promise){//回调返回的值或者resolve的值是Promise对象时需要等待该Promise对象的状态变更
        value.then(promise.resolve.bind(promise),promise.reject.bind(promise));
    } else if (type(value) === 'Object' || type(value) === 'Function') {
        try {
            then = value.then;
        } catch(getThenErr) {
            promise.reject(thenErr);
        }
        if (type(then) === 'Function') {
            try {
                then.call(value,promise.resolve.bind(promise),promise.reject.bind(promise));
            } catch(callThenErr) {
                if (promise.state === 'pending') {
                    promise.reject(callThenErr);
                } 
            }
        } else {
            ret = true;
            var fn;
            promise.setState('fulfilled');//设置当前Promise状态的状态和值
            promise.value = value;
            var error;
            while (fn = promise._resolve.shift()) {//执行resolve回调队列里的函数
                try {
                    if (typeof fn == 'function') {
                        var result = fn(value);
                        promise.value = result;
                    } 
                } catch (err) {
                    ret || (ret = err);//记录第一个执行出错的函数的异常信息
                }
            }
        }
    }  else {
        ret = true;
        var fn;
        promise.setState('fulfilled');//设置当前Promise状态的状态和值
        promise.value = value;
        var error;
        while (fn = promise._resolve.shift()) {//执行resolve回调队列里的函数
            try {
                if (typeof fn == 'function') {
                    var result = fn(value);
                    promise.value = result;
                } 
            } catch (err) {
                (ret instanceof Error) || (ret = err);
            }
        }
    }

    if (promise.next) {
        if (ret === true) {
            resolve_promise_value(promise.next,promise.value);
        }
        else if (ret instanceof Error){
            promise.next.reject(ret);    
        }
    }

}

function type(arg) {//判断对象类型函数
    return  Object.prototype.toString.call(arg).match(/ (\w+)/)[1];
}

function Promise(fn,value,state) {
    if (!(this instanceof Promise)) {//防止不用new调用Promise函数
        return new Promise(fn);
    }
    this._resolve = [];//Promise对象的fulfilled时执行的回调队列
    this._reject = [];//Promise对象的rejected时执行的回调队列
    this.next = null;//执行下一个Promise对象
    this.value = value || null;//当前Promise对象的值
    this.state = state || 'pending';//当前Promise对象的状态
    this.id = Promise.idFactory();
    /*
        new 的时候如果有函数,就执行该函数,把resolve和reject函数作为参数传进去,并且绑定对应的Promise对象
    */
    try {
      fn && fn(this.resolve.bind(this),this.reject.bind(this));
    } catch (e) {
      this.reject(e);
    }
}

Promise.prototype = {
    equal: function(promise) {//根据id判断两个Promise对象是否相等
        return promise && (type(promise.then) === 'Function') && (this.id === promise.id);
    },
    resolve: function(value) {
        if(this.state !== 'pending'){
            return;
        }
        setTimeout((function() {
            resolve_promise_value(this,value)
        }).bind(this),0);

    },
    setState: function(state) {//设置Promise对象的状态
        this.state = state;
    },
    reject: function(value) {
        if (this.state === 'pending') {
            setTimeout((function() {
                this.setState('rejected');//设置Promise对象状态
                this.value = value;//记录Promise对象对应的值
                var fn;
                var error;
                if (this._reject.length === 0) {
                    if (this.next) {
                        this.next.reject(value);
                    }
                    return;
                }
                while (fn = this._reject.shift()) {//执行reject回调函数
                    try {
                        if (typeof fn == 'function') {//对于回调函数队列,只需记录最后一个函数的执行结果
                            var result = fn(value);
                            this.value = result;
                        } 
                    } catch (err) {//捕获异常,保证回调队列里的函数每一个都被执行
                        error || (error = err);
                    }
                }
                if (this.next) {
                    if (error) {
                        this.next.reject(error);
                    } 
                    /*
                        执行完当前Promise对象的回调后,如果Promise链上有下一个Promise对象,继续执行,当前的Promise对象的值传进去
                        如果error为true则说明上面代码执行中有异常,把异常对象传给下一个Promise对象
                    */
                    else {
                        resolve_promise_value(this.next,result);
                    }
                }
            }).bind(this),0)

        }
    },
    then: function(resolve,reject) {//增加resolve和reject回调
        if (this.state != 'pending') {//如果当前Promise对象已经resolve或reject则根据当前Promise对象状态异步执行传进来的resolve或reject函数
            this.state === 'fulfilled' ? (resolve = resolve || function() {}) : (reject = reject || function() {});
            setTimeout(this.state === 'fulfilled' ? resolve.bind(null,this.value) : reject.bind(null,this.value),0);
            return;
        }
        (type(resolve) === 'Function') && this._resolve.push(resolve);//记录resolve回调
        (type(reject) === 'Function') && this._reject.push(reject);
        this.next = new Promise();//返回一个新的Promise对象
        return this.next;
    },
    catch: function(reject) {//then(undefined,callback)的语法糖
        return this.then(void 0,reject);
    }
}
Promise.all = function(promiseArr) {
    if (type(promiseArr) !== 'Array') {//参数需要Promise数组
        new Error('need a Array');
    }
    var count = 0;
    var result = [];//记录每个Promise的结果
    var ret = new Promise();//返回新的Promose对象
    for (var i = 0; i< promiseArr.length ;i++) {
        promiseArr[i].then((function(i) {//每个Promise fulfilled后记录结果并且判断是否全部Promise对象已经fulfilled
            return function(value) {
                result[i] = value;
                count++;
                if (count === promiseArr.length) {//全部Promise fulfilled的话就执行resovle
                    ret.resolve(result); 
                }
            }
        })(i),function(value) {
            if (ret.state === 'pending') {//有一个Promise对象reject并且ret还是pending状态的话就直接返回
                ret.reject(value);
            }    
        })
    }
    return ret;
}

Promise.race = function(promiseArr) {
    if (type(promiseArr) !== 'Array') {
        new Error('need a Array');
    }
    var ret = new Promise();
    for (var i = 0; i< promiseArr.length ;i++) {
        promiseArr[i].then(function(value) {
            if (ret.state === 'pending') {//有一个Promise对象resolve的话就返回,并且放弃其余的Promise对象的结果
                ret.resolve(value);
            }
        },function(value) {
            if (ret.state === 'pending') {//有一个Promise对象reject的话就返回,并且放弃其余的Promise对象的结果
                ret.reject(value);
            }    
        });
    }
    return ret;
}

Promise.resolve = function(arg) {
    if (arg && arg instanceof Promise) {//参数是Promise对象的话直接返回
        return arg;
    } else {//否则用参数构造一个Promise对象
        var result = new Promise((arg && arg.then) || null,(arg && arg.then) ? null : arg,'fulfilled');
        //result.resolve(arg);
        return result;
    }
}

Promise.reject = function(arg) {//同resolve
    if (arg && arg instanceof Promise) {
        return arg;
    } else {
        var result = new Promise((arg && arg.then) || null,(arg && arg.then) ? null : arg,'reject');
        //result.reject(arg);
        return result;
    }
}
Promise.idFactory = (function() {//id构造工厂,id用于比较是否是同一个Promise对象
    var _id = 0;
    return function() {
        return _id += 1;
    }
})();

module.exports = Promise;
JavaScript 中的 `Promise` 对象是用来处理异步操作的一种数据结构。它表示了一个尚未完成的任务,并允诺在将来提供一个结果。Promise 可以处于三种状态之一:pending(待定)、fulfilled(已完成,成功) 或 rejected(已完成,失败)。在实际应用中,通常会通过 `then` 和 `catch` 方法来链式处理这些状态变化。 ### 创建简单的 Promise 构造函数 下面是一个基础的 `Promise` 的实现示例: ```javascript function simplePromise(value) { return new Promise(function(resolve, reject) { // 根据值判断是否是已经成功的状态 if (value === true) { resolve("任务成功!"); } else { reject("任务失败!"); } }); } ``` 在这个简单的 `simplePromise` 函数里,我们创建了一个 `Promise` 对象并传入了两个回调函数作为参数:`resolve` 和 `reject`。这两个函数分别用于处理 `fulfilled` 状态和 `rejected` 状态。 ### 使用简单 `Promise` 实现的功能 一旦我们有了这个构造函数,就可以使用它来包装异步操作。例如: ```javascript simplePromise(true) .then(result => console.log(result)) .catch(error => console.error(error)); ``` 上述代码将首先尝试执行 `simplePromise(true)`,由于给定的 `true` 表示成功,因此会进入 `.then` 方法并打印出 "任务成功!” 到控制台。如果在实现中使用了 `false` 或其他导致错误的情况,则会触发 `.catch` 方法并打印错误信息。 ### 扩展功能 为了更完整地体现 `Promise` 的功能,可以进一步增加返回结果、处理多个状态等特性。比如添加返回值的能力以及 `finally` 方法供清理操作使用: ```javascript class SimplePromise { constructor(executor) { this.resolve = null; this.reject = null; this.state = 'pending'; this.value = null; const resolveReject = (state, value) => { if (this.state === 'pending') { this.state = state; this.value = value; if (this.resolve && this.reject) { this.resolve(this.value); this.reject = undefined; this.resolve = undefined; } } }; try { executor(resolveReject); } catch(e) { resolveReject('rejected', e); } } then(onFulfilled, onRejected) { return new SimplePromise((resolve, reject) => { this.resolve = (result) => { try { let x = onFulfilled ? onFulfilled(result) : result; if (x instanceof SimplePromise) { x.then(resolve, reject); } else { resolve(x); } } catch(e) { reject(e); } }; this.reject = error => { try { let x = onRejected ? onRejected(error) : error; if (x instanceof SimplePromise) { x.then(resolve, reject); } else { reject(x); } } catch(e) { reject(e); } }; }); } catch(rejectHandler) { return this.then(null, rejectHandler); } finally(callback) { let promise = this; return this.then(() => callback(), () => callback()); } } // 使用新的 Promise 类 new SimplePromise((resolve, reject) => { setTimeout(() => resolve('Hello'), 500); }).then(result => console.log(result)).catch(err => console.error(err)); ``` 在这个版本中,我们引入了类封装来简化 API 和增强功能,如允许返回值、链式调用 `then` 方法和通过 `finally` 完成清理操作。 --- ### 相关问题 - JavaScript Promise 的基本概念: 1. **Promise 的状态是什么?** 分别解释它们的意义及如何从 `pending` 转变到其他状态。 2. **简述 `.then()` 和 `.catch()` 方法的作用以及区别。** 3. **在什么情况下使用 `.finally()` 方法?给出一个场景说明它的用途。** 通过这些问题,你可以更深入地理解 Promise 结构和其在 JavaScript 异步编程中的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值