Promise笔记

1.函数对象与实例对象的区别

  1. 函数对象与实例对象
    - 函数对象:将函数作为对象使用时,简称为函数对象
    - 实例对象:new 函数产生的对象,简称为对象
		 function Fn() {

        }
        const fn = new Fn();//Fn是构造函数  fn是实例对象(简称为对象)
        console.log(Fn.prototype);
        Fn.call({});//Fn是函数对象
        $('#test');  // JQuery函数   括号的左边是函数
        $.get('/test');// JQuery函数对象 .左边是对象

        function Person() {

        }

2.回调函数的分类

  1. 同步回调:
    1. 理解:立即执行,完全执行完了才结束,不会放入回到队列中
    2. 例子:数组遍历相关的回调函数 / Promise的excutor函数
  2. 异步回调:
    1. 理解:不会理解执行,会放入回调队列中将来执行
    2. 例子:定时器回调 / ajax回调 / Promise的成功|失败的回调
 		 // // 1.同步回调函数
        // const arr = [1, 2, 3];
        // arr.forEach(item => { // 遍历回调,同步回到函数,不会放入队列,一上来就执行完

        //     console.log(item);
        // })
        // console.log('ForEach()之后');

        // 2.异步回调
        setTimeout(function () {//异步回调函数,会放入队列中将来执行
            console.log('timeout callback');
        }, 0)
        console.log('setTImeou()之后执行');

3.JS中的错误(Error)和错误处理

目标:进一步理解JS中的错误(Error)和错误处理
mdn文档: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error

   1.错误的类型
        Error:所有错误的父类型
        ReferenceError:引用的变量不存在
        TypeError:数据类型不正确的错误
        RangeError:数据值不在其所允许的范围内
        SyntaxError:语法错误
    2.错误处理
        捕获错误:try...catch
        抛出错误:throw error
    3.错误对象
        message属性:错误相关信息
        stack属性:函数调用栈记录信息
  // 1.ReferenceError:引入变量不存在
        // console.log(a);// ReferenceError: a is not defined
        // console.log('-------');// 没有捕获error,下面的代码不会执行
        // 2.TypeError:数据类型不正确的错误
        // let b = null;
        // let b = undefined;
        // let b;
        // console.log(b.xxx);//TypeError: Cannot read properties of undefined (reading 'xxx')
        // let b;
        // b.xxx();//TypeError: Cannot read properties of undefined (reading 'xxx')
        // 3. RangeError:数据值不在其所允许的范围内
        // function fn() {
        //     fn();//递归调用,函数自己调用自己
        // }
        // fn(); //RangeError: Maximum call stack size exceeded
        // const c = "''";
        // 4.SyntaxError:语法错误
        // const c = """" ;//SyntaxError: Unexpected string

        // 2.错误处理
        //     捕获错误:try...catch

        try {
            let b
            console.log(b.xxx);
        } catch (error) {
            // console.log(error);
            console.log(error.message);
            console.log(error.stack);
        }

        //     抛出错误:throw error
        function something() {
            if (Date.now() % 2 === 1) {
                console.log('当前事件为奇数,可以执行任务')
            } else { //如果事件是偶数抛出异常,由调用来处理
                throw new Error('当前时间为偶数,无法执行任务')
            }
        }

        //  捕获处理异常
        try {
            something();
        } catch (error) {
            alert(error.message);
        }

4.promise基本使用

		 // // 1. 创建一个新的promise对象
        // const p = new Promise((resolve, reject) => {
        //     // 2.执行异步操作任务
        //     setTimeout(() => {
        //         const time = Date.now();
        //         // 3.1. 如果成功了,调用resolve(value)
        //         if (time % 2 == 0) {
        //             resolve('成功的数据,time =' + time);
        //         } else {
        //             // 3.2. 如果失败了,调用reject(reason)
        //             reject('失败的数据,time=' + time)
        //         }
        //     }, 1000)
        // })
        // p.then(value => {//接收到成功的value数据
        //     console.log('成功的回调', value);
        // }, reason => {//接收到失败的reason数据
        //     console.log('失败的回调', reason);
        // })

        const p = new Promise((resolve, reject) => { //执行器函数  同步回调
            console.log('执行了excutor');
            setTimeout(function () {
                const time = Date.now();
                if (time % 2 == 0) {
                    resolve('成功的数据,time=' + time);
                } else {
                    reject('失败的数据,time=' + time)
                }
            }, 1000)
        })
        // console.log('new Promise()之后');
        setTimeout(function () {
            p.then(value => {//接收到成功的value数据    onResolved
                console.log('成功的回调', value)
            }, reason => {//接收到失败的reason数据      onRejected
                console.log('失败的回调', reason)
            })
        }, 2000)

5.为什么要用Promise

  1. 指定回到函数的方式更加灵活:
    1. 旧的:必须在启动异步任务前指定
    2. promise:启动异步任务 => 返回Promise对象 => 给Promise对象绑定回调函数(甚至可以在异步任务启动之后)
  2. 支持链式调用,可以解决回到地狱问题
    1. 什么是回调地狱?回到函数嵌套掉用,外部回到函数异步执行的结果是嵌套的回调函数执行的条件
    2. 回调地狱的缺点?不便于约定 / 不便于异常处理
    3. 解决方案? promise链式调用
    4. 终极解决方案? async/await
  // 成功的回调函数
        function successCallbakc(result) {
            console.log('声音文件创建成功:' + result);
        }
        // 失败的回调函数
        function successCallbakc(result) {
            console.log('声音文件创建成功:' + result);
        }
        // 1.1使用纯回调函数
        createdAudioFileAsync(audioSetting, successsCallback, failureCallback);//伪代码

        // 2.1 回调函数
        doSomething(function (result) {
            doSomethingElse(result, function (ewResult) {
                doThirdThing(newResult, function (finalResult) {
                    console.log('Got the final reuslt:' + finalResult);
                })
            })
        })
        // 2.2使用promise的链式调用解决回调地狱
        // catch 异常传透
        doSomething().then(function (result) {
            return doSomethingElse(reuslt)
        }).then(function (newResult) {
            return doTHirdThing(newResult);
        }).then(function (finalResult) {
            console.log('Got the final reuslt:' + finalResult);
        })
            .catch(failureCallback)

            // 2.3 async/await:回到地狱的终极解决方案
        async function request() {
            try {
                const reuslt = await doSomething();
                const newResult = await doSomethingElse(result);
                const finalResult = await doThirdThing(newResult);
                console.log('Got the final reuslt:' + finalResult);
            }catch(error){
                failureCallback(error);
            }
        }

6.Promise的API

 		1.Promise构造函数:Promise(excutor){
            excutor函数:同步执行(resolve,reject) => {}
            resolve函数:内部定义成功时我们调用的函数,value => {}
            reject函数:内部定义失败时我们调用的函数 reason => {}
            说明: excutor会在Promise内部定立即同步回调,异步操作在执行器中执行 

        2.Promise.prototype.then方法:(onResolved,onRejected) => {}
            onResolved函数:成功的回调函数  (value) => {}
            onRejected函数: 失败的回调函数  (reason) => {}
            说明:指定用于得到成功value的成功的回调和用于得到失败reason的失败的回调
                  返回一个新的promise对象
        
        3.Promise.prototype.catch方法:(onRejected) =>{}
            onRejected函数:失败的回调函数 (reason) => {}
            说明:then()的语法糖,相当于:then(undefined,onRejected)

        4.Promise.resolve方法:(value) =>{}
            value:成功的数据或promise对象
            说明:返回一个成功/失败的promise对象
        
        5.Promise.rejected方法:(reason) => {}
            reason:失败的原因
            说明:返回一个失败的promise对象

        6.Promise.all方法:(promise) => {}
            promise:包含n个promise的数组
            说明:返回一个新的promise,自由所有的promise都成功才陈宫,只要有一个事变了就直接失败

        7.Promise.race方法:(promise) => {}
            promise:包含n个promise的数组
            说明:返回一个新的promise,第一个完成promise的结果状态就是最终的结果状态
		// new Promise((resolve, reject) => {
        //     setTimeout(function () {
        //         // resolve('成功的数据');
        //         reject('失败的数据');
        //     }, 1000)
        // }).then(value => {
        //     console.log('onResolved()1', value);
        // }).catch(reason => {
        //     console.log('onRejected()1', reason);
        // })

        // 产生一个成功值为1的promised对象
        const p1 = new Promise((resolve, reject) => {
            resolve(1)
        })
        const p2 = Promise.resolve(2);
        const p3 = Promise.resolve(3);
        const p4 = Promise.reject(1);
        // p1.then(value => { console.log(value) })
        // p2.then(value => { console.log(value) })
        // p3.then(value => { console.log(value) })
        // p4.catch(reason => { console.log(reason) })

        // const pAll = Promise.all([p1, p2, p3, p4]);
        const pAll = Promise.all([p1, p2, p3]);
        // pAll.then(values => {
        //     console.log('all onResolved()', values);
        // },
        //     reason => {
        //         console.log('all onRejected', reason);
        //     }
        // )

        const pRace = Promise.race([p4, p1, p2, p3]);
        pRace.then(value => {
            console.log('race onResolved()', value);
        },
            reason => {
                console.log('race onRejected()', reason);
            }
        )

7.promise的几个关键问题1

	1. 如何改变promise的状态
        (1)resolve(value): 如果当前是pending就会变为resolved
        (2)reject(reason): 如果当前是pending就会变为rejected
        (3)抛出异常: 如果当前是pending就会变为rejected

    2. 一个promise指定多个成功/失败回调函数,都会调用吗?
        当promise改变为对应状态时都会调用
    	const p = new Promise((resolve, reject) => {
            // resolve(1);//promise变为resolved成功状态
            // reject(2);//promise变为rejected失败状态
            // throw new Error('出错了!');//抛出异常,promise变为rejected失败状态,reason为抛出的error
            throw 3;//抛出异常,promise变为rejected失败状态,reason 为抛出的3
        })
        // console.log(p);
        p.then(value => {
            console.log(value);
        }, reason => {
            console.log(reason);
        })

        p.then(value => {
            console.log(value);
        }, reason => {
            console.log(reason);
        })

7.promise的几个关键问题2

3.改变promise状态和指定回调函数谁先谁后?
        (1)都有可能,正常情况下是先指定回调函数在改变状态,但也可能先改变状态在指定回调
        (2)如何先改状态再指定回调?
            (1)在执行器中直接调用resolve()/rejected()
            (2)延迟更长时间才调用then()
        (3)什么时候才能得到数据?
            (1)如果先指定回调,那当状态发生改变时,回调函数就调用,得到数据
            (2)如果先改变的状态,那当指定回调是,回调哈数就会掉用,得到数据
   		// 常规:先指定回调函数,后改变的状态
        //  new Promise((resolve, reject) => {
        //     setTimeout(function () {
        //         resolve(1) // 后改变状态(同时指定数据),异步执行回调函数
        //     }, 1000)
        // }).then(value => { //先指定回调函数,保存当前指定的回调函数
        //     console.log(value);
        // }, reason => {
        //     console.log(reason);
        // })

        // 如果先改变状态,后指定回调函数
        new Promise((resolve, reject) => {
            resolve(1) // 先改变状态(同时指定数据)
        }).then(value => { //后指定回调函数,异步执行回调函数
            console.log('vlaue2',value);
        }, reason => {
            console.log('reason2', reason);
        })
        console.log('----- -');

        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(1)
            }, 1000)
        })
        setTimeout(() => {
            p.then(
                value => { console.log('value3', value); },
                reason => { console.log('reason', reason) }
            )
        }, 1100)

7.promise的几个关键问题3

	  4.promise.then()返回的新promise的结果状态由什么决定?
            (1).简单表达:由then()指定的回调函数执行的结果决定
            (2).详细表达:
                (1).如果抛出异常,新promise变为rejected,reason为抛出的异常
                (2).如果返回的是非promise的任意值,新promise变为resolved, value为返回值
                (3).如果返回的是 另一个新promise,此promise的结果就会成为新promise的结果
new Promise((resolve, reject) => {
            // resolve(1)
            reject(2)
        }).then(
            value => {
                console.log('onResolved1()', value);
                // return 2;
                // return Promise.resolve(2)
                // return Promise.reject('错处了2')
                throw 5;
            },
            reason => {
                
                console.log('onRejected1()', reason);//这个值没有掉promise返回的是成功还是失败
            }
        ).then(
            value => {
                console.log('onResolved2()', value);
            },
            reason => {
                console.log('onRejected2()', reason);
            }
        )

7.promise的几个关键问题3

    5.promise如何串联多个操作任务?
        (1)promise的then()返回一个新的promise,可以开成then()的链式调用
        (2)通过then的链式调用串联多个同步/异步任务
 		new Promise((resolve, reject) => {
            //  resolve(1) 同步
            setTimeout(() => {
                console.log('执行任务1(异步)');
                resolve(1)
            }, 1000)
        }).then(
            value => {
                console.log('任务1的结果', value);
                console.log('执行了任务2(同步)');
                return 2;
            }
        ).then(
            value => {
                console.log('任务2的结果', value);
                // 启动任务3(异步)
                return new Promise((resolve, reject) => {
                    setTimeout(() => {
                        console.log('执行任务3(异步)');
                        resolve(3);
                    }, 1000)
                })

            }
        ).then(value => {
            console.log(value);
        })

7.promise的几个关键问题5

	6.promise异常传/穿透
        (1)当使用promise的then链式调用时,可以在最后指定失败的回调
        (2)前面任何操作出了异常,都会传到最后失败的回调处理中
    7.终端promise链?
        (1)当使用promise的then链式调用时,在中间中断,不在调用后面的回调函数
        (2)办法:在回调函数中返回一个pending状态的promise对象
 		new Promise((resolve, reject) => {
            //  resolve(1) 同步
            // setTimeout(() => {
            //     console.log('执行任务1(异步)');
            //     resolve(1)
            // }, 1000)
            reject(1)
        }).then(
            value => {
                console.log('任务1的结果', value);
                console.log('执行了任务2(同步)');
                return 2;
            },
            reason => { throw reason }

        ).then(
            value => {
                console.log('任务2的结果', value);
                // 启动任务3(异步)
                // return new Promise((resolve, reject) => {
                //     setTimeout(() => {
                //         console.log('执行任务3(异步)');
                //         resolve(3);
                //     }, 1000)
                // })
                return 3;
            },
            reason => { throw reason }

        ).then(value => {
            console.log(value);
            reason => reason
            // reason => { throw reason}
            // return Promise.reject('wwwwwww');
        }).catch(reason => {
            console.log('onRejected1()', reason);
            // throw reason
            return Promise.reject(reason)
        }).then(
            value => {
                console.log('onResolved3()', reason);

            },
            reason => {
                console.log('onRejected2()', reason);
            }
        )

8.自定义Promise

Promise1_整体结构
/*
    自定义Promise函数模块:IIFE (匿名函数自调用---立即执行函数)
*/

(function (window) {
    /*
    Promise构造函数
    executor:执行器函数
    */
    function Promise(executor) {
        self.status = PENDING; // 给promise对象指定status属性初始值为pending
        self.data = undefined //给promsie对象指定给一个用于存储结果数据的属性
        self.callbacks = [] //每个元素的结构:{onResolved

        function reasolve(value) {
        // 如果当前状态不是pending,直接结束

        // 将状态改为resolved
        
        // 如果有待执行callBack函数,立即异步执行回调函数onResolved
                
        }

        function reject(reason) {

        }
        // 立即同步执行executor
        executor(reasolve, reject)
    }

    /*
    Promise原型对象的then()
    指定成功和失败的回调函数
    返回一个新的promise对象
    */

    // 返回一个新的Promise
    Promise.prototype.then = function (onResolved, onRejected) {

    }

    /*
        Promise原型对象的catch()
        指定失败的回调函数
    */
    Promise.prototype.catch = function (onRejected) {

    }


    /* 
    Promise函数对象resolve方法 
    返回一个指定结果的成功的promise
    */
    Promise.resolve = function (value) {

    }
    /* 
    Promise函数对象reject方法 
    返回一个指定reason的失败的promise
    */
    Promise.reject = function (reason) {

    }

    /* 
        Promise函数对象的all方法
        返回一个promise,只有当所有的promise都成时才成功,否则只要有一个失败的就失败
    */
    Promise.all = function (promise) {

    }

    /*  
        Promise函数对象的race方法
        返回一个promise,其结果由第一个完成的promise决定
    */
    Promise.race = function (promise) {

    }

    // 向外暴露Promise函数
    window.Promise = Promise;
})(window)


Promise2_Promise构造函数
/*
    自定义Promise函数模块:IIFE (匿名函数自调用---立即执行函数)
*/

(function (window) {
    const PENDING = 'pending';
    const RESOLVED = 'resolved';
    const REJECTED = 'rejected';

    /*
    Promise构造函数
    executor:执行器函数
    */
    function Promise(executor) {
        const self = this;
        self.status = PENDING; // 给promise对象指定status属性初始值为pending
        self.data = undefined //给promsie对象指定给一个用于存储结果数据的属性
        self.callbacks = [] //每个元素的结构:{onResolved(){},onRejected(){}}

        function resolve(value) {
            // 如果当前状态不是pending,直接结束
            if (self.status !== PENDING) {
                return
            }

            // 将状态改为resolved
            self.status = RESOLVED;
            // 保存value
            self.data = value;
            // 如果有待执行callBack函数,立即异步执行回调函数onResolved
            if (self.callbacks.length > 0) {
                setTimeout(() => { //让如队列中执行所有成功的回调
                    self.callbacks.forEach(callbacksObj => {
                        callbacksObj.onResolved(value)
                    })
                });
            }
        }
        function reject(reason) {
            // 如果当前状态不是pending,直接结束
            if (self.status !== PENDING) {
                return
            }

            // 将状态改为rejected
            self.status = REJECTED;
            // 保存value
            self.data = reason;
            // 如果有待执行callBack函数,立即异步执行回调函数onRejected
            if (self.callbacks.length > 0) {
                setTimeout(() => { //让如队列中执行所有失败的回调
                    self.callbacks.forEach(callbacksObj => {
                        callbacksObj.onRejected(reason)
                    })
                });
            }
        }

        // 立即同步执行executor
        try {
            executor(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }

    /*
    Promise原型对象的then()
    指定成功和失败的回调函数
    返回一个新的promise对象
    返回的promise的结果由onResolved/onRejected执行结果决定    
    */

    // 返回一个新的Promise
    Promise.prototype.then = function (onResolved, onRejected) {
      
    }

    /*
        Promise原型对象的catch()
        指定失败的回调函数
        返回一个新的promise对象
    */
    Promise.prototype.catch = function (onRejected) {
        return this.then(undefined, onRejected)
    }


    /* 
    Promise函数对象resolve方法 
    返回一个指定结果的成功的promise
    */
    Promise.resolve = function (value) {
    
    }
    /* 
    Promise函数对象reject方法 
    返回一个指定结果的失败的promise

    */
    Promise.reject = function (reason) {
     
    }

    /* 
        Promise函数对象的all方法
        返回一个promise,只有当所有的promise都成时才成功,否则只要有一个失败的就失败

    */
    Promise.all = function (promise) {

    }

    /*  Promise函数对象的race方法
       返回一个promise,其结果由第一个完成的promise决定
    */
    Promise.race = function (promise) {

    }

    // 向外暴露Promise函数
    window.Promise = Promise;
})(window)


Promise3_then方法&catch方法
/*
    自定义Promise函数模块:IIFE (匿名函数自调用---立即执行函数)
*/

(function (window) {
    const PENDING = 'pending';
    const RESOLVED = 'resolved';
    const REJECTED = 'rejected';

    /*
    Promise构造函数
    executor:执行器函数
    */
    function Promise(executor) {
        const self = this;
        self.status = PENDING; // 给promise对象指定status属性初始值为pending
        self.data = undefined //给promsie对象指定给一个用于存储结果数据的属性
        self.callbacks = [] //每个元素的结构:{onResolved(){},onRejected(){}}

        function resolve(value) {
            // 如果当前状态不是pending,直接结束
            if (self.status !== PENDING) {
                return
            }

            // 将状态改为resolved
            self.status = RESOLVED;
            // 保存value
            self.data = value;
            // 如果有待执行callBack函数,立即异步执行回调函数onResolved
            if (self.callbacks.length > 0) {
                setTimeout(() => { //让如队列中执行所有成功的回调
                    self.callbacks.forEach(callbacksObj => {
                        callbacksObj.onResolved(value)
                    })
                });
            }
        }
        function reject(reason) {
            // 如果当前状态不是pending,直接结束
            if (self.status !== PENDING) {
                return
            }

            // 将状态改为rejected
            self.status = REJECTED;
            // 保存value
            self.data = reason;
            // 如果有待执行callBack函数,立即异步执行回调函数onRejected
            if (self.callbacks.length > 0) {
                setTimeout(() => { //让如队列中执行所有失败的回调
                    self.callbacks.forEach(callbacksObj => {
                        callbacksObj.onRejected(reason)
                    })
                });
            }
        }

        // 立即同步执行executor
        try {
            executor(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }

    /*
    Promise原型对象的then()
    指定成功和失败的回调函数
    返回一个新的promise对象
    返回的promise的结果由onResolved/onRejected执行结果决定    
    */

    // 返回一个新的Promise
    Promise.prototype.then = function (onResolved, onRejected) {
        // 当前promsie对象
        const self = this;

        // 指定回调函数的默认值(必须是函数)
        onResolved = typeof onResolved === 'function' ? onResolved : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

        return new Promise((resolve, reject) => {
            /*
                执行指定的回调函数
                根据执行的结果改变为return的promise状态/数据
            */
            function handle(callback) {
                /*
                    返回的promise的结果由onResolved/onRejected执行结果决定    
                    1.抛出异常,返回promise的结果为失败,reason为异常
                    2.返回的是promis,返回promise的结果就是这个结果
                    3.返回的不是promis,返回promise未成功,value就是成功值
                */
                try {
                    const result = callback(self.data) // 错误
                    if (result instanceof Promise) { // 2.返回的是promis,返回promise的结果就是这个结果
                        // result.then(
                        //     value => resolve(value),
                        //     reason => reject(reason),
                        // )
                        result.then(resolve, reject);
                    } else {//  3.返回的不是promis,返回promise未成功,value就是成功值
                        resolve(result)
                    }
                } catch (error) {
                    reject(error);
                }
            }


            // 当前promise的状态是resolved
            if (self.status === RESOLVED) {
                // 立即异步执行成功的回调函数
                setTimeout(() => {
                    handle(onResolved)
                })
            } else if (self.status === REJECTED) {// 当前promise的状态是rejected
                // 立即异步执行失败的回调函数
                setTimeout(() => {
                    handle(onRejected)
                })
            } else {// 当前promise的状态是pending
                // 将成功和失败的回调函数报存callback容器中缓存起来
                self.callbacks.push({
                    onResolved(value) {
                        handle(onResolved)
                    },
                    onRejected(reason) {
                        handle(onRejected)
                    }
                })
            }


        })
    }

    /*
        Promise原型对象的catch()
        指定失败的回调函数
        返回一个新的promise对象
    */
    Promise.prototype.catch = function (onRejected) {
        return this.then(undefined, onRejected)
    }


    /* 
    Promise函数对象resolve方法 
    返回一个指定结果的成功的promise
    */
    Promise.resolve = function (value) {
 
    }
    /* 
    Promise函数对象reject方法 
    返回一个指定结果的失败的promise

    */
    Promise.reject = function (reason) {
    
    }

    /* 
        Promise函数对象的all方法
        返回一个promise,只有当所有的promise都成时才成功,否则只要有一个失败的就失败

    */
    Promise.all = function (promise) {

    }

    /*  Promise函数对象的race方法
       返回一个promise,其结果由第一个完成的promise决定
    */
    Promise.race = function (promise) {

    }

    // 向外暴露Promise函数
    window.Promise = Promise;
})(window)

Promise4的resolved和rejected方法
/*
    自定义Promise函数模块:IIFE (匿名函数自调用---立即执行函数)
*/

(function (window) {
    const PENDING = 'pending';
    const RESOLVED = 'resolved';
    const REJECTED = 'rejected';

    /*
    Promise构造函数
    executor:执行器函数
    */
    function Promise(executor) {
        const self = this;
        self.status = PENDING; // 给promise对象指定status属性初始值为pending
        self.data = undefined //给promsie对象指定给一个用于存储结果数据的属性
        self.callbacks = [] //每个元素的结构:{onResolved(){},onRejected(){}}

        function resolve(value) {
            // 如果当前状态不是pending,直接结束
            if (self.status !== PENDING) {
                return
            }

            // 将状态改为resolved
            self.status = RESOLVED;
            // 保存value
            self.data = value;
            // 如果有待执行callBack函数,立即异步执行回调函数onResolved
            if (self.callbacks.length > 0) {
                setTimeout(() => { //让如队列中执行所有成功的回调
                    self.callbacks.forEach(callbacksObj => {
                        callbacksObj.onResolved(value)
                    })
                });
            }
        }
        function reject(reason) {
            // 如果当前状态不是pending,直接结束
            if (self.status !== PENDING) {
                return
            }

            // 将状态改为rejected
            self.status = REJECTED;
            // 保存value
            self.data = reason;
            // 如果有待执行callBack函数,立即异步执行回调函数onRejected
            if (self.callbacks.length > 0) {
                setTimeout(() => { //让如队列中执行所有失败的回调
                    self.callbacks.forEach(callbacksObj => {
                        callbacksObj.onRejected(reason)
                    })
                });
            }
        }

        // 立即同步执行executor
        try {
            executor(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }

    /*
    Promise原型对象的then()
    指定成功和失败的回调函数
    返回一个新的promise对象
    返回的promise的结果由onResolved/onRejected执行结果决定    
    */

    // 返回一个新的Promise
    Promise.prototype.then = function (onResolved, onRejected) {
        // 当前promsie对象
        const self = this;

        // 指定回调函数的默认值(必须是函数)
        onResolved = typeof onResolved === 'function' ? onResolved : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

        return new Promise((resolve, reject) => {
            /*
                执行指定的回调函数
                根据执行的结果改变为return的promise状态/数据
            */
            function handle(callback) {
                /*
                    返回的promise的结果由onResolved/onRejected执行结果决定    
                    1.抛出异常,返回promise的结果为失败,reason为异常
                    2.返回的是promis,返回promise的结果就是这个结果
                    3.返回的不是promis,返回promise未成功,value就是成功值
                */
                try {
                    const result = callback(self.data) // 错误
                    if (result instanceof Promise) { // 2.返回的是promis,返回promise的结果就是这个结果
                        // result.then(
                        //     value => resolve(value),
                        //     reason => reject(reason),
                        // )
                        result.then(resolve, reject);
                    } else {//  3.返回的不是promis,返回promise未成功,value就是成功值
                        resolve(result)
                    }
                } catch (error) {
                    reject(error);
                }
            }


            // 当前promise的状态是resolved
            if (self.status === RESOLVED) {
                // 立即异步执行成功的回调函数
                setTimeout(() => {
                    handle(onResolved)
                })
            } else if (self.status === REJECTED) {// 当前promise的状态是rejected
                // 立即异步执行失败的回调函数
                setTimeout(() => {
                    handle(onRejected)
                })
            } else {// 当前promise的状态是pending
                // 将成功和失败的回调函数报存callback容器中缓存起来
                self.callbacks.push({
                    onResolved(value) {
                        handle(onResolved)
                    },
                    onRejected(reason) {
                        handle(onRejected)
                    }
                })
            }


        })
    }

    /*
        Promise原型对象的catch()
        指定失败的回调函数
        返回一个新的promise对象
    */
    Promise.prototype.catch = function (onRejected) {
        return this.then(undefined, onRejected)
    }


    /* 
    Promise函数对象resolve方法 
    返回一个指定结果的成功的promise
    */
    Promise.resolve = function (value) {
        // 返回一个成功/失败的promise
        return new Promise((resolve, reject) => {
            // value是promise
            if (value instanceof Promise) { //使用value的结果作为promise的结果
                value.then(resolve, reject)
            } else { // value不是promise => promise变为成功,数据是value
                resolve(value)
            }
        })
    }
    /* 
    Promise函数对象reject方法 
    返回一个指定结果的失败的promise

    */
    Promise.reject = function (reason) {
        // 返回一个失败的promise
        return new Promise((resolve, reject) => {
            reject(reason)
        })
    }

    /* 
        Promise函数对象的all方法
        返回一个promise,只有当所有的promise都成时才成功,否则只要有一个失败的就失败

    */
    Promise.all = function (promise) {

    }

    /*  Promise函数对象的race方法
       返回一个promise,其结果由第一个完成的promise决定
    */
    Promise.race = function (promise) {

    }

    // 向外暴露Promise函数
    window.Promise = Promise;
})(window)


Promise5_Promise的all和race方法
/*
    自定义Promise函数模块:IIFE (匿名函数自调用---立即执行函数)
*/

(function (window) {
    const PENDING = 'pending';
    const RESOLVED = 'resolved';
    const REJECTED = 'rejected';

    /*
    Promise构造函数
    executor:执行器函数
    */
    function Promise(executor) {
        const self = this;
        self.status = PENDING; // 给promise对象指定status属性初始值为pending
        self.data = undefined //给promsie对象指定给一个用于存储结果数据的属性
        self.callbacks = [] //每个元素的结构:{onResolved(){},onRejected(){}}

        function resolve(value) {
            // 如果当前状态不是pending,直接结束
            if (self.status !== PENDING) {
                return
            }

            // 将状态改为resolved
            self.status = RESOLVED;
            // 保存value
            self.data = value;
            // 如果有待执行callBack函数,立即异步执行回调函数onResolved
            if (self.callbacks.length > 0) {
                setTimeout(() => { //让如队列中执行所有成功的回调
                    self.callbacks.forEach(callbacksObj => {
                        callbacksObj.onResolved(value)
                    })
                });
            }
        }
        function reject(reason) {
            // 如果当前状态不是pending,直接结束
            if (self.status !== PENDING) {
                return
            }

            // 将状态改为rejected
            self.status = REJECTED;
            // 保存value
            self.data = reason;
            // 如果有待执行callBack函数,立即异步执行回调函数onRejected
            if (self.callbacks.length > 0) {
                setTimeout(() => { //让如队列中执行所有失败的回调
                    self.callbacks.forEach(callbacksObj => {
                        callbacksObj.onRejected(reason)
                    })
                });
            }
        }

        // 立即同步执行executor
        try {
            executor(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }

    /*
    Promise原型对象的then()
    指定成功和失败的回调函数
    返回一个新的promise对象
    返回的promise的结果由onResolved/onRejected执行结果决定    
    */

    // 返回一个新的Promise
    Promise.prototype.then = function (onResolved, onRejected) {
        // 当前promsie对象
        const self = this;

        // 指定回调函数的默认值(必须是函数)
        onResolved = typeof onResolved === 'function' ? onResolved : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

        return new Promise((resolve, reject) => {
            /*
                执行指定的回调函数
                根据执行的结果改变为return的promise状态/数据
            */
            function handle(callback) {
                /*
                    返回的promise的结果由onResolved/onRejected执行结果决定    
                    1.抛出异常,返回promise的结果为失败,reason为异常
                    2.返回的是promis,返回promise的结果就是这个结果
                    3.返回的不是promis,返回promise未成功,value就是成功值
                */
                try {
                    const result = callback(self.data) // 错误
                    if (result instanceof Promise) { // 2.返回的是promis,返回promise的结果就是这个结果
                        // result.then(
                        //     value => resolve(value),
                        //     reason => reject(reason),
                        // )
                        result.then(resolve, reject);
                    } else {//  3.返回的不是promis,返回promise未成功,value就是成功值
                        resolve(result)
                    }
                } catch (error) {
                    reject(error);
                }
            }


            // 当前promise的状态是resolved
            if (self.status === RESOLVED) {
                // 立即异步执行成功的回调函数
                setTimeout(() => {
                    handle(onResolved)
                })
            } else if (self.status === REJECTED) {// 当前promise的状态是rejected
                // 立即异步执行失败的回调函数
                setTimeout(() => {
                    handle(onRejected)
                })
            } else {// 当前promise的状态是pending
                // 将成功和失败的回调函数报存callback容器中缓存起来
                self.callbacks.push({
                    onResolved(value) {
                        handle(onResolved)
                    },
                    onRejected(reason) {
                        handle(onRejected)
                    }
                })
            }


        })
    }

    /*
        Promise原型对象的catch()
        指定失败的回调函数
        返回一个新的promise对象
    */
    Promise.prototype.catch = function (onRejected) {
        return this.then(undefined, onRejected)
    }


    /* 
    Promise函数对象resolve方法 
    返回一个指定结果的成功的promise
    */
    Promise.resolve = function (value) {
        // 返回一个成功/失败的promise
        return new Promise((resolve, reject) => {
            // value是promise
            if (value instanceof Promise) { //使用value的结果作为promise的结果
                value.then(resolve, reject)
            } else { // value不是promise => promise变为成功,数据是value
                resolve(value)
            }
        })
    }
    /* 
    Promise函数对象reject方法 
    返回一个指定结果的失败的promise

    */
    Promise.reject = function (reason) {
        // 返回一个失败的promise
        return new Promise((resolve, reject) => {
            reject(reason)
        })
    }

    /* 
        Promise函数对象的all方法
        返回一个promise,只有当所有的promise都成时才成功,否则只要有一个失败的就失败

    */
    Promise.all = function (promises) {
        // 用来保存所有成功value的数组
        const values = new Array(promises.length);
        // 用来保存成功promise的数量
        let resolvedCount = 0;
        return new Promise((resolve, reject) => {
            // 遍历promises获取每个promise的结果
            promises.forEach((p, index) => {
                Promise.resolve(p).then(
                    value => {
                        resolvedCount++; // 成功的数量+1
                        // p成功,将成功的value保存values
                        // values.push(value) 
                        values[index] = value;

                        // 如果全部成功了,将return的promise改为成功
                        if (resolvedCount === promises.length) {
                            resolve(values)
                        }
                    },
                    reason => { //只要有一个失败了,return的promise就失败
                        reject(reason)
                    }
                )
            })
        })
    }

    /*  Promise函数对象的race方法
       返回一个promise,其结果由第一个完成的promise决定
    */
    Promise.race = function (promises) {
        // 返回一个promise
        return new Promise((resolve, reject) => {
            // 遍历promises获取每个promise的结果
            promises.forEach((p, index) => {
                Promise.resolve(p).then(
                    value => { //一旦有成功了,将return变为成功
                        resolve(value)
                    },
                    reason => {//一旦有失败了,将return变为失败
                        reject(reason)
                    }
                )
            })
        })
    }

    // 向外暴露Promise函数
    window.Promise = Promise;
})(window)

// function fn(event) {

// }

// div.onclick = function (event) {
//     fn(event)
// }


Promise_class实现
/*
    自定义Promise函数模块:IIFE (匿名函数自调用---立即执行函数)
*/

(function (window) {
    const PENDING = 'pending';
    const RESOLVED = 'resolved';
    const REJECTED = 'rejected';

    /*
    Promise构造函数
    excutor:执行器函数
    */
    class Promise {
        constructor(excutor) {
            const self = this;
            self.status = PENDING; // 给promise对象指定status属性初始值为pending
            self.data = undefined //给promsie对象指定给一个用于存储结果数据的属性
            self.callbacks = [] //每个元素的结构:{onResolved(){},onRejected(){}}

            function resolve(value) {
                // 如果当前状态不是pending,直接结束
                if (self.status !== PENDING) {
                    return
                }

                // 将状态改为resolved
                self.status = RESOLVED;
                // 保存value
                self.data = value;
                // 如果有待执行callBack函数,立即异步执行回调函数onResolved
                if (self.callbacks.length > 0) {
                    setTimeout(() => { //让如队列中执行所有成功的回调
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onResolved(value)
                        })
                    });
                }
            }
            function reject(reason) {
                // 如果当前状态不是pending,直接结束
                if (self.status !== PENDING) {
                    return
                }

                // 将状态改为rejected
                self.status = REJECTED;
                // 保存value
                self.data = reason;
                // 如果有待执行callBack函数,立即异步执行回调函数onRejected
                if (self.callbacks.length > 0) {
                    setTimeout(() => { //让如队列中执行所有失败的回调
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onRejected(reason)
                        })
                    });
                }
            }

            // 立即同步执行excutor
            try {
                excutor(resolve, reject)
            } catch (error) {
                reject(error)
            }
        }


        /*
        Promise原型对象的then()
        指定成功和失败的回调函数
        返回一个新的promise对象
        返回的promise的结果由onResolved/onRejected执行结果决定    
        */

        // 返回一个新的Promise
        then(onResolved, onRejected) {
            // 当前promsie对象
            const self = this;

            // 指定回调函数的默认值(必须是函数)
            onResolved = typeof onResolved === 'function' ? onResolved : value => value;
            onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

            return new Promise((resolve, reject) => {
                /*
                    执行指定的回调函数
                    根据执行的结果改变为return的promise状态/数据
                */
                function handle(callback) {
                    /*
                        返回的promise的结果由onResolved/onRejected执行结果决定    
                        1.抛出异常,返回promise的结果为失败,reason为异常
                        2.返回的是promis,返回promise的结果就是这个结果
                        3.返回的不是promis,返回promise未成功,value就是成功值
                    */
                    try {
                        const result = callback(self.data) // 错误
                        if (result instanceof Promise) { // 2.返回的是promis,返回promise的结果就是这个结果
                            // result.then(
                            //     value => resolve(value),
                            //     reason => reject(reason),
                            // )
                            result.then(resolve, reject);
                        } else {//  3.返回的不是promis,返回promise未成功,value就是成功值
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error);
                    }
                }


                // 当前promise的状态是resolved
                if (self.status === RESOLVED) {
                    // 立即异步执行成功的回调函数
                    setTimeout(() => {
                        handle(onResolved)
                    })
                } else if (self.status === REJECTED) {// 当前promise的状态是rejected
                    // 立即异步执行失败的回调函数
                    setTimeout(() => {
                        handle(onRejected)
                    })
                } else {// 当前promise的状态是pending
                    // 将成功和失败的回调函数报存callback容器中缓存起来
                    self.callbacks.push({
                        onResolved(value) {
                            handle(onResolved)
                        },
                        onRejected(reason) {
                            handle(onRejected)
                        }
                    })
                }


            })
        }

        /*
            Promise原型对象的catch()
            指定失败的回调函数
            返回一个新的promise对象
        */
        catch(onRejected) {
            return this.then(undefined, onRejected)
        }


        /* 
        Promise函数对象resolve方法 
        返回一个指定结果的成功的promise
        */
        static resolve = function (value) {
            // 返回一个成功/失败的promise
            return new Promise((resolve, reject) => {
                // value是promise
                if (value instanceof Promise) { //使用value的结果作为promise的结果
                    value.then(resolve, reject)
                } else { // value不是promise => promise变为成功,数据是value
                    resolve(value)
                }
            })
        }
        /* 
        Promise函数对象reject方法 
        返回一个指定结果的失败的promise
    
        */
        static reject = function (reason) {
            // 返回一个失败的promise
            return new Promise((resolve, reject) => {
                reject(reason)
            })
        }

        /* 
            Promise函数对象的all方法
            返回一个promise,只有当所有的promise都成时才成功,否则只要有一个失败的就失败
    
        */
        static all = function (promises) {
            // 用来保存所有成功value的数组
            const values = new Array(promises.length);
            // 用来保存成功promise的数量
            let resolvedCount = 0;
            return new Promise((resolve, reject) => {
                // 遍历promises获取每个promise的结果
                promises.forEach((p, index) => {
                    Promise.resolve(p).then(
                        value => {
                            resolvedCount++; // 成功的数量+1
                            // p成功,将成功的value保存values
                            // values.push(value) 
                            values[index] = value;

                            // 如果全部成功了,将return的promise改为成功
                            if (resolvedCount === promises.length) {
                                resolve(values)
                            }
                        },
                        reason => { //只要有一个失败了,return的promise就失败
                            reject(reason)
                        }
                    )
                })
            })
        }

        /*  Promise函数对象的race方法
           返回一个promise,其结果由第一个完成的promise决定
        */
        static race = function (promises) {
            // 返回一个promise
            return new Promise((resolve, reject) => {
                // 遍历promises获取每个promise的结果
                promises.forEach((p, index) => {
                    Promise.resolve(p).then(
                        value => { //一旦有成功了,将return变为成功
                            resolve(value)
                        },
                        reason => {//一旦有失败了,将return变为失败
                            reject(reason)
                        }
                    )
                })
            })
        }

        /*
         返回一个promise对象,他在指定的时间后才确定结果
        */
        static resolveDelay = function (value, time) {
            // 返回一个成功/失败的promise
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    // value是Promise
                    if (value instanceof Promise) { // 使用value的结果作为promise的结果
                        value.then(resolve, reject)
                    } else { //value不是promise => promise变为成功,数据是value
                        resolve(value)
                    }
                }, time)
            })
        }

        /* 
            返回一个promise对象,它在指定的时间后才失败
        */
        static rejectDelay = function (reason, time) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    reject(reason)
                }, time)
            })
        }
    }

    // 向外暴露Promise函数
    window.Promise = Promise;
})(window)

9.async与await

目标:进一步掌握async/await的语法和使用
        mdn文档:
            https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function
            https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await
        1.async函数
            函数的返回值为promise对象
            promise对象的结果由async函数执行的返回值决定

        2.await表达式
            await右侧的表达式一般为promise对象,但也可以是其它的值
            如果表达式是promise对象,await返回的是promise成功的值
            如果表达式是其他值,直接将此值作为await的返回值

        3.注意:
            await必须写在async函数中,但async函数中可以没有await
            如果await的promise失败了,就会抛出异常,需要通过try...catch来捕获异常
  		// async函数的返回值是一个promise对象
        // async函数返回的promise的结果由函数执行的结果决定
        async function fn1() {
            return 1
            // throw 2
            // return Promise.reject(2);
            // return Promise.resolve(3);
            // return new Promise((resolve, reject) => {
            //     setTimeout(() => {
            //         resolve(4)
            //     }, 1000)
            // })
        }
        const result = fn1();
        // console.log(result);
        result.then(
            value => { console.log('onResolved()', value); },
            reason => { console.log('onRejected()', reason); }
        )


        function fn2() {
            // return 2;
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(5);
                }, 1000)
            })
        }

        function fn4() {
            return 6;
        }
        async function fn3() {
            // await是then的成功的回调的值,也就是resolve的value值
            // const value = await fn2(); //await右侧表达式为promise,得到的结果就是promise成功的value
            try {
                // const value = await fn2(); // await右侧表达式不是promise,得到的结果就是它本身
                const value = await fn1();
                console.log('value', value);
            } catch (error) {
                console.log('得到失败的结果', error);
            }

            //const value = await fn4(); // await右侧表达式不是promise,得到的结果就是它本身
            //console.log('value', value);
        }
        fn3();

10.宏队列与微队列

		 setTimeout(() => { // 会立即放入宏队列
            console.log('tiemout callback1()');
        }, 0)

        setTimeout(() => {
            console.log('tiemout callback2()');
        }, 0)
        Promise.resolve(1).then(
            value => { // 会立即放入微队列
                console.log('Promise onResolved1()', value);
            }
        )
        Promise.resolve(2).then(
            value => { // 会立即放入微队列
                console.log('Promise onResolved2()', value);
            }
        )

在这里插入图片描述

Promise相关面试题1


//结果: 3 2 4 1
  		setTimeout(() => {
            console.log(1);
        }, 0)

        Promise.resolve().then(() => {
            console.log(2);
        })

        Promise.resolve().then(() => {
            console.log(4);
        })
        console.log(3);

Promise相关面试题2

  // 结果:25341
 		setTimeout(() => {
            console.log(1); // 宏队列的第一个宏任务
        }, 0)

        new Promise((resolve) => {
            console.log(2); //这里是同步执行的代码,一执行到这里的代码就立即输出2
            resolve();
        }).then(() => {
            console.log(3);  //微队列里的第一个微任务
        }).then(() => {
            console.log(4); //微队列里的第二个微任务
        })
        console.log(5);  //同步代码

      

Promise相关面试题3

 // 定义了一个变量等于一个箭头,而且这个箭头函数返回的是一个promise对象
        const frist = () => (new Promise((resolve, reject) => {
            console.log(3); //同步执行的代码
            // 里面又new了一个Promise
            let p = new Promise((resolve, reject) => {
                console.log(7);// 同步执行的代码,执行器函数是同步执行  
                setTimeout(() => {
                    // 异步执行的代码
                    console.log(5);
                    // 但是还执行resolve(6),当我前面都反复处理过了,反复调用resolve没用
                    // 没用,状态已经改变了
                    resolve(6);
                }, 0)
                // 同步执行p成功的promise的回调函数;
                resolve(1);
            });
            // 同步执行frist成功的promsie的回调函数;
            resolve(2);
            // p成功的回调函数
            p.then((arg) => {
                // .thenc成功的回调函数
                console.log(arg);
            }
            )
        }));

        // 同步执行的frist() log(4)
        // frist成功的回调函数
        frist().then(arg => {
            // .thenc成功的回调
            console.log(arg);
        })
        console.log(4);

Promise相关面试题4

        /*  
                1 7 2 3 8 4 6 5 0
            同步:1 7 2 3 8 4 6 5 0
            宏:[0 ] 
            微:[]
			最后得出的结果: 1 7 2 3 8 4 6 5 0
        */
        setTimeout(() => {
            console.log('0');
        }, 0)
        new Promise((resolve, reject) => {
            console.log('1'); //执行器同步执行
            resolve(); //调用resolve,让这个promise成功,成功了但是还没回调函数
        }).then(() => {   // .then 也是同步执行
            console.log('2');
            new Promise((resolve, reject) => {
                console.log('3');
                resolve();
            }).then(() => {
                console.log('4');
            }).then(() => {
                console.log('5');
            })
        }).then(() => {
            console.log('6');  //又有一个.then,不会立即放入微队列里面去,因为上面的微队列还没执行
        })

        new Promise((resolve, reject) => {
            console.log('7');
            resolve();
        }).then(() => {
            console.log('8');
        })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值