Promise笔记

什么是Promise?

1.抽象表达:
Promise是JS中进行异步编程的新的解决方案。
2.具体表达:
从语法上来说: Promise是一个构造函数
从功能上来说: promise对象用来封装一个异步操作并可以获取其结果
3. promise的状态改变(只有2种, 只能改变一次)
pending变为resolved
pending变为rejected
4. promise的基本流程
Promise笔记_第1张图片

一个 Promise 必然处于以下几种状态之一:
待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
已兑现(resolved): 意味着操作成功完成。
已拒绝(rejected): 意味着操作失败。

为什么要用Promise?

  1. 指定回调函数的方式更加灵活: 可以在请求发出甚至结束后指定回调函数
  2. 支持链式调用, 可以解决回调地狱问题

Promise的常用API:

静态方法:
1.Promise.all(iterable) 这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。
2.Promise.race(iterable) 当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。
3.Promise.reject(reason) 返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法
4.Promise.resolve(value) 返回一个状态由给定value决定的Promise对象。value可能是一个普通值也可能是一个Promise
Promise 原型:
1.Promise.prototype.catch(onRejected) 添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入resolved状态,则以当前promise的完成结果作为新promise的完成结果.
2.Promise.prototype.then(onResolved, onRejected) 添加解决(resolve)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve.

基本使用Promise:

let myFirstPromise = new Promise(function(resolve, reject){
    //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
    //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
    setTimeout(function(){
        resolve("成功!"); //代码正常执行!
    }, 250);
});

myFirstPromise.then(function(successMessage){
    //successMessage的值是上面调用resolve(...)方法传入的值.
    //successMessage参数不一定非要是字符串类型,这里只是举个例子
    console.log("Yay! " + successMessage);
});

自定义Promise:

/* 
    自定义promise模块
*/
(function(window) {
    const PENDING = "pending"; //初始值未确定状态
    const RESOLVED = "resolved"; //成功状态
    const REJECTED = "rejected"; //失败状态
    // Promise构造函数
    function Promise(excutor) {
        const that = this;
        that.status = PENDING; //指定状态属性,初始值为pending,代表初始值未确定状态
        that.data = undefined; //用来存储结果数据的属性,初始值为undefined
        that.callbacks = []; // {onResolved(){},onRejected(){}}
        //将promise的状态改为,指定成功的value
        function resolve(value) {
            //如果当前状态不是pending。直接结束
            if (that.status !== PENDING) return;
            that.status = RESOLVED;
            that.data = value;
            //调用所有缓存的待执行成功的回调函数
            if (that.callbacks.length > 0) {
                //启动一个延迟时间为0的定时器,在定时器的回调函数中执行所有成功的回调函数
                setTimeout(() => {
                    that.callbacks.forEach(obj => {
                        obj.onResolved(value);
                    })
                })
            };
        };
        //将promise的状态改为失败,指定失败的resaon
        function reject(reason) {
            //如果当前状态不是pending。直接结束
            if (that.status !== PENDING) return;
            that.status = REJECTED;
            that.data = reason;
            //调用所有缓存的待执行失败的回调函数
            if (that.callbacks.length > 0) {
                //启动一个延迟时间为0的定时器,在定时器的回调函数中执行所有失败的回调函数
                setTimeout(() => {
                    that.callbacks.forEach(obj => {
                        obj.onRejected(reason);
                    })
                })
            }
        };
        //调用promise的状态改为失败,指定失败的reason
        try {
            excutor(resolve, reject);
        } catch (error) { //执行器执行错误,当前promise变为失败
            reject(error);
        }
    };
    /* 用来指定成功/失败回调函数的方法
                1.如果当前promise是pending,保存回调函数。
                2.如果当前promise是resolved,异步执行成功的onResolved。
                3.如果当前promise是rejected,异步执行成功的onRejected。
            返回一个新的promise对象
                它的结果状态由onResolved或onRejected执行的结果决定
                1.抛出error => 变为rejected,结果值为error
                2.返回值不是promise => 变为resolved,结果值为返回值
                3.返回值是promise => 由这个promise的决定新的promise的结果(成功/失败)
    
        */
    Promise.prototype.then = function(onResolved, onRejected) {
        const that = this;
        onResolved = typeof onResolved === 'function' ? onResolved : value => value; //将value向下传递
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }; //将reason向下传递
        return new Promise((resolve, reject) => {
            //1.调用指定的回调函数callback
            //2.根据callback()执行的结果更新then()返回的promise的状态
            function handle(callback) {
                try {
                    const result = callback(that.data);
                    if (!result instanceof Promise) {
                        resolve(result);
                    } else {
                        result.then( //取回调函数返回promise结果
                            value => resolve(value),
                            reason => reject(reason)
                        );
                        // result.then(resolve, reject);
                    }
                } catch (error) {
                    reject(error);
                }
            }
            if (that.status === RESOLVED) {
                setTimeout(() => {
                    handle(onResolved);
                });
            } else if (that.status === REJECTED) {
                setTimeout(() => {
                    handle(onRejected);
                });
            } else {
                that.callbacks.push({ //不是直接保存成功/失败的回调,保存包含了回调函数的调用
                    onResolved(value) {
                        handle(onResolved);
                    },
                    onRejected(reason) {
                        handle(onRejected);
                    }
                })
            }
        });

    };
    //用来指定失败回调函数的方法
    Promise.prototype.catch = function(onRejected) {
        return this.then(undefined, onRejected);
    };
    //用来返回一个指定value的成功的Promise
    //value可能是一个一般的值,也可能是promise对象;
    Promise.resolve = function(value) {
        return new Promise((resolve, reject) => {
            //如果value是一个promise,最终返回的是promise的结果由value决定
            if (value instanceof Promise) {
                value.then(resolve, reject);
            } else { //value不是promise,返回的是成功的promise,成功的值就是value
                resolve(value);
            }
        })
    };
    //用来返回一个指定reason的失败的Promise
    Promise.reject = function(reason) {
        return new Promise((resolve, reject) => {
            reject(reason);
        })
    };
    //返回一个promise,只有当数组所有promise都成功才成功,否则失败
    Promise.all = function(promises) {
        return new Promise((resolve, reject) => {
            let resolvedCount = 0; //已成功的数量
            const values = new Array(promises.length); //用来保存成功promise的value值
            promises.forEach((p, index) => {
                p.then(value => {
                    resolvedCount++;
                    values[index] = value;
                    if (resolvedCount === promises.length) { //都成功了
                        resolve(values);
                    }
                });
            })
        })
    };
    //返回一个promise,由第一个promise决定
    Promise.race = function(promises) {
        return new Promise((resolve, reject) => {
            promises.forEach(p => {
                p.then(resolve, reject);
            })
        })
    };
    // 向外面暴露Promise
    window.Promise = Promise;
})(window)

你可能感兴趣的:(js模块化,javascript,es6,typescript)