深度详解Promise

Promise之执行器
本质上Promise就是一个构造函数。
Promise的实例对象有三个状态
pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 意味着操作成功完成。(resolved)
rejected: 意味着操作失败
 Promise语法
new Promise( function(resolve, reject) {…}); //第一个参数一般我们称为executor
//实例
var promise = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, ‘foo’);
});
 executor

executor是带有 resolve 和 reject 两个参数的函数 。Promise构造函数执行时立即调用executor 函数,在实例对象被返回前。resolve 和 reject 两个函数作为参数传递给executor。resolve 和 reject 函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。executor 内部通常会执行一些异步操作,一旦完成,可以调用resolve函数来将promise状态改成fulfilled,或者在发生错误时调用reject函数将它的状态改为rejected。如果在executor函数中抛出一个错误,那么该promise 状态为rejected。executor函数的返回值被忽略。

执行器是一个同步的回调函数
执行器是一个高阶函数
大忌:不能再执行器中直接同步的决定promise的状态
promise实例对象具有三个状态:初始化状态,成功状态,失败状态
promise实例对象的状态可以触发一系列回调的这个事是一次性的!!!
promise实例对象的状态切换 是我们学习promise的核心
promise实例对象是可以拥有值!!!
先有执行器的调用,才有promise实例对象的生成
 var promise = new Promise(function (resolve, reject) {
        //再执行器中一定要抒写异步代码
        //让定时器来模拟ajax请求
        setTimeout((flag,data)=>{
            if(flag){
                //请求成功
                resolve(data)
            }else{
                //请求失败
                reject("网络断了!!!")
            }
        },1000,true,"one")

        //当前返回的promise具备了实际的意义  当它的状态产生改变时 代表的就是我们的请求成功与否!
    })

 Promise.prototype.then
当promise对象的状态发生改变时,绑定在其身上的then方法中的两个参数会被选择性的注册一个。
then方法包含两个参数:onfulfilled函数 和 onrejected函数,它们都是 Function 类型。当Promise状态为fulfilled时,注册 then 的 onfulfilled 方法,当Promise状态为rejected时,注册 then 的 onrejected 方法, 所以在异步操作的完成和绑定处理方法之间不存在竞争
then() 方法返回一个 Promise 。

// 关注then方法返回的promise的状态是如何改变的!值又是如何分配的!
    // 最佳实践 then方法的回调参数中一定要返回一个promise
    new Promise(function (resolve, reject) {
        setTimeout((flag,data)=>{
            if(flag){
                resolve(data)
            }else{
                reject("网络断了!!!")
            }
        },1000,true,"one")
    })
    .then((data)=>{
        console.log("第一次数据获取成功:"+data);
        return new Promise((resolve, reject)=>{
            setTimeout((flag,data)=>{
                if(flag){
                    resolve(data)
                }else{
                    reject("网络断了!!!")
                }
            },1000,true,"two")
        })
    })
    .then((data)=>{
        console.log("第二次数据获取成功:"+data);
        return new Promise((resolve, reject)=>{
            setTimeout((flag,data)=>{
                if(flag){
                    resolve(data)
                }else{
                    reject("网络断了!!!")
                }
            },1000,true,"three")
        })
    })

    .then((data)=>{
        console.log("第三次数据获取成功:"+data);
    })

 async&await
正常函数前加一个async关键字后,该函数就被定义成了一个async函数。
当调用一个 async 函数时,会返回一个 Promise 对象。
当这个 async 函数返回一个值时,Promise 的 resolve 方法会负责传递这个值;
当 async 函数抛出异常时,Promise 的 reject 方法也会传递这个异常值。
 await
await 操作符用于等待一个Promise 对象。它只能在async function 中使用。
await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。
若 Promise 正常处理(fulfilled),!!其回调的resolve函数参数作为 await 表达式的值!!,继续执行 async function。
若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。

  /* async函数返回的promise的 状态&持有的值
    当async函数返回一个非promise的值时;async函数返回的promise;变为成功状态;持有的值是async函数返回的值
    当async函数返回一个promise时 那就看这个promise的状态和值
    当async函数抛出异常时;async函数返回的promise变为失败状态;持有的值是异常信息*/

    async function test() {
        console.log("test");
        throw new Error("0000")
    }

    var promise =  test()
    console.log(promise);

await


    async function test() {
        const data1 = await new Promise(function (resolve, reject) {
            setTimeout((flag,data)=>{
                if(flag){
                    resolve(data)
                }else{
                    reject("网络断了!!!")
                }
            },1000,true,"one")
        });
        console.log("第一次数据获取成功:"+data1);

        const data2 = await new Promise((resolve, reject)=>{
            setTimeout((flag,data)=>{
                if(flag){
                    resolve(data)
                }else{
                    reject("网络断了!!!")
                }
            },1000,true,"two")
        })
        console.log("第二次数据获取成功:"+data2);

        const data3 = await new Promise((resolve, reject)=>{
            setTimeout((flag,data)=>{
                if(flag){
                    resolve(data)
                }else{
                    reject("网络断了!!!")
                }
            },1000,true,"three")
        })
        console.log("第三次数据获取成功:"+data3);
    }
    test()

async的异常处理

 async function test() {
        // try {
            const data1 = await new Promise(function (resolve, reject) {
                setTimeout((flag,data)=>{
                    if(flag){
                        resolve(data)
                    }else{
                        reject("网络断了!!!")
                    }
                },1000,false,"one")
            });
            console.log("第一次数据获取成功:"+data1);

            const data2 = await new Promise((resolve, reject)=>{
                setTimeout((flag,data)=>{
                    if(flag){
                        resolve(data)
                    }else{
                        reject("网络断了!!!")
                    }
                },1000,true,"two")
            })
            console.log("第二次数据获取成功:"+data2);

            const data3 = await new Promise((resolve, reject)=>{
                setTimeout((flag,data)=>{
                    if(flag){
                        resolve(data)
                    }else{
                        reject("网络断了!!!")
                    }
                },1000,true,"three")
            })
            console.log("第三次数据获取成功:"+data3);
        // }catch (e) {
        //     console.log(e,"-----");
        // }
    }

    test().catch((err)=>{
        console.log(err);
    })

1、promise面试题
输出值问题



同步:1723
微队列:8,4,6,5
宏队列:0
 // 输出:  1 7 2 3 8 4 6 5 0
  setTimeout(() => {console.log("0")}, 0)
  new Promise((resolve,reject)=>{
    console.log("1")
    resolve()
  }).then(()=>{        
    console.log("2")
    new Promise((resolve,reject)=>{
      console.log("3")
      resolve()
    }).then(()=>{      
      console.log("4")
    }).then(()=>{       
      console.log("5")
    })
  }).then(()=>{  
    console.log("6")
  })
  new Promise((resolve,reject)=>{
    console.log("7")
    resolve()
  }).then(()=>{         
    console.log("8")
  })
  先执行同步输出,
  因为new Promise里面的回调函数是异步,v8引擎先执行后面的几个then方法,调用线程池里面的线程来持有then,根据得到状态的先后顺序分别把他们放入微队列中,等待v8来顺序执行。先进的先执行,执行完了才能接着放下一个等待被放入的持有then线程.
要分清楚回调函数的注册和执行,他们是分开的,回调函数什么时候会被执行,v8有空了,就会被执行。

同级的谁在前就先把谁放微队列。
例如,两个并行的new Promise
先输出第一个的1,再输出第二个的7,
然后同级别的then也是谁在前先把谁放入微队列。
    满足条件之后:2*+,再8
    满足条件之后:4,6

2、异常错误的传递
        new Promise((resolve, reject)=>{
            setTimeout(()=>{
                reject("xxx")
            },2000)
        })
        .then(()=>{})
        .then(()=>{})
        .then(()=>{})
        .then(()=>{})
        .catch((reason)=>{console.log(reason);})
  reject抛出异常以后,后面的.then只有写一个参数才能将异常信息传递到最后一个catch哪里去。
  如果写了第二个参数来接收,返回值为undefined,那么then的返回的promise状态就会为成功。最后的catch接收不到异常。
async面试题:
    async function test() {
        await new Promise(function(resolve, reject){
            setTimeout(function(){
                console.log(1)
                resolve()
            },2000)
        })
    }
    (async ()=>{
        await test()
        console.log(2)
    })()
使用一个自调用async来包裹另外一个async test()函数 在他的前面加上await来卡点,达到先执行异步回调函数,再来执行同步回调,提高代码的易读性。 


错误的await代码,切记await 后面一定要跟new  promise

    // await 后一定要跟promise!!!!

    Promise.resolve(1).then((data1)=>{
        console.log("第一次数据获取成功:"+data1);
        return 2
    }).then((data2)=>{
        console.log("第二次数据获取成功:"+data2);
        return 3
    }).then((data3)=>{
        console.log("第三次数据获取成功:"+data3);
    })
    /*async function test() {
        const data1 = await 1

        console.log("第一次数据获取成功:"+data1);

        const data2 = await 2

        console.log("第二次数据获取成功:"+data2);

        const data3 = await 3

        console.log("第三次数据获取成功:"+data3);
    }
    test()*/

Promise笔记

可以返回一个promise的api

new Promise((resolve,reject)=>{})
    状态&持有的值
        默认是初始化状态;持有的值是undefined
        当执行器的第一个参数resolve(val)被调用时;promise变为成功状态;持有的值是val
        当执行器的第二个参数reject(reason)被调用时;promise变为失败状态;持有的值是reason
        当执行器抛出异常时;promise变为失败状态;持有的值是异常信息

Promise.prototype.then(onResolve,onReject)
    状态&持有的值
        默认是初始化状态;持有的值是undefined
        当then的任意一个回调进入队列并被执行后;then返回的promise的状态就可以确定了
            当这个回调返回一个非promise的值时;then返回的promise;变为成功状态;持有的值是这个回调返回的值
            当这个回调返回一个promise时;then返回的promise和回调返回的promise保持一致
            当这个回调抛出异常时;then返回的promise变为失败状态;持有的值是异常信息

promise的状态机制

当promise发生改变时;如果其已经调用了then方法;那then方法中两个参数;会被选择性的塞入到队列中
    如果promise变为成功状态 则then的第一个参数进微队列
    如果promise变为失败状态 则then的第二个参数进微队列
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值