• Promise


    Promise

    什么是Promise

    Promise 是ES6引入的异步编程的一种解决方案,语法上讲是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果

    可以看到Promise自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法
    在这里插入图片描述

    Promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。函数体封装一个异步的操作

    Promise的三种状态

    Promise的三种状态:等待(pending)、已完成(fulfilled)、已拒绝(rejected)

    1. pending: 等待 (进行中) promise一创建出来,状态就是pending进行中
    2. fulfilled: 成功 (已完成), 调用 resolve, 就会将状态从pending改成fulfilled, 且将来就会执行.then,fulfilled,又称resolved
    3. rejected: 失败 (已拒绝), 调用 reject, 就会将状态从pending改成rejected, 且将来就会执行.catch

    每个Promise对象都有状态,且状态为上述三种之一

    创建Promise对象时,且没有调用resolve或者是reject方法,相当于是初始状态。这个初始状态会随着你调用resolve,或者是reject函数而切换到另一种状态。

    一个promise的状态只可能从“等待”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换
    在这里插入图片描述

    • 具体含义:

      pending

      是一个等待最终结果的状态,也是一个初始状态,如果你在函数中不调用resolve,reject,最终都是一个一直等待的状态,但是不调用,并没有什么意义,一般常用与调用resolve、reject给与相应的状态,总结:你只需要知道这是一个等待最终结果的状态,至于之后会发生的状态,并不会知道

      fulfilled

      fulfilled代表已兑现、成功 ,意思是承诺兑现了 从pending====>fulfilled 的过程,在之前的浏览器版本可能会出现resolved的情况都是代表成功,当调用resolve函数时 就会进入成功(fulfilled )的状态

      rejected

      rejected: 代表拒绝,失败,意思是承诺没有实现从pending===>rejected的过程 当调用 失败(reject)的状态

    • 状态转换

      promise的状态转换只能发生一次,一旦当前状态变为“已完成”或“失败”,就意味着不会再有新的状态变化了。因此,Promise对象的最终结果只有两种。(一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为resolved和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果)

      promise必须实现then方法(可以说,then就是promise的核心),而且then必须返回一个promise,同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致

      then方法接受两个参数,第一个参数是成功时的回调,在promise由“等待”态转换到“完成”态时调用,另一个是失败时的回调,在promise由“等待”态转换到“拒绝”态时调用。同时,then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。

      通过.then添加的回调函数,不论什么时候,都会被调用,而且可以添加多个回调函数,会一次按照顺序并且独立运行。

    promise的 resolve 和 reject参数
     // 箭头函数   
     let p1 = new Promise((resolve,reject)=>{})
     // 普通声明
     let p2 = new Promise(function (resolve,reject) {}) 
    
    • 1
    • 2
    • 3
    • 4

    而函数中的两个形参(resolve,reject) 也是函数形式,但这两个只是形参的名字 实际上你写什么都可以,只不过我们通常约定写这两个形参名。

    Promise.resolve('foo')
    // 等价于
    new Promise(resolve => resolve('foo'))
    
    • 1
    • 2
    • 3

    resolve, reject 可以在设置状态的同时可以传递 1 个数据(最多一个数据,也可不传),给 then / catch。

    PromiseState代表状态,PromiseResult 代表值 resolve、reject 调用时传入的数据

    1、不调用函数时,promise的状态为pending。

    let p1 = new Promise((resolve,reject)=>{})
    console.log(p1);
    
    • 1
    • 2

    在这里插入图片描述

    调用 resolve 函数, 代表 Promise的状态 会从 pending 变为 fulfilled。

     let p2 = new Promise((resolve,reject)=>{
                 resolve(1)
             })
    console.log(p2);
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    3、调用 reject 函数 , 代表 promise的状态 会从 pending 变为 rejected 。

     let p3 = new Promise((resolve,reject)=>{
                reject(1);
             })
    console.log(p3);
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4、当状态一旦发生改变 就不会重新改变 例如已经从pending 到 fulfilled 了就不会重新改变到 rejected

             let p1 = new Promise((resolve,reject)=>{
                resolve()
                reject()
             })
            console.log(p1);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    只会从 pending状态到fulfilled状态,并不会去执行最后的rejected 状态

    then、 catch 、finally方法

    then、catch、finally方法是定义在原型对象Promise.prototype上的

    promise 中 提供了 then 和 catch 两个方法, 分别用来处理 fulfilled (已成功) 和 rejected(已失败)的状态。

    1、如果 promise 状态为 fulfilled , 则调用 then 方法来处理对应的成功的逻辑。

    let promise = new Promise(function(resolve, reject){
    	resolve() ;
    }); 
    promise.then(function() {
    	console.log("成功了");
    })
    promise.catch(function() {
    	console.log("失败了");
    })
    //打印 成功了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2、如果 promise 状态为 rejected , 则调用 catch 方法来处理对应的失败的逻辑。

    let promise = new Promise(function(resolve, reject){
    	reject() ;
    }); 
    promise.then(function() {
    	console.log("成功了");
    })
    promise.catch(function() {
    	console.log("失败了");
    })
    //打印 失败了,该处promise状态有疑问?
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    • then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。两个函数只会有一个被调用。
    • then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例),因此可以采用链式写法,即then方法后面再调用另一个then方法
    • catch()方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数
    • finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作

    Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数

    Promise三种状态

    Promise.all()

    Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例

    const p = Promise.all([p1, p2, p3]);
    
    
    • 1
    • 2

    Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例

    p的状态由p1、p2、p3决定,分成两种情况。

    (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

    (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

    promise.then 返回的新的promise结果状态由什么决定的?
    1. 简单表达:由.then内指定的回调函数(执行的回调函数)的返回结果来决定
    2. 详细表达:
      • 回调函数没有返回值:返回一个状态resolved,value为undefined的新promise实例对象
      • 回调函数如果抛出异常(throw new Error(‘error’)):返回一个状态rejected,reason为抛出的异常值( new Error()内的值)的新promise实例对象
      • 回调函数如果返回的是非promise的任意值:返回一个状态resolved,value为返回值的新promise实例对象
      • 回调函数如果返回值是一个新的promise实例对象(这个实例对象状态改变以后再将状态结果向下一个then传递):这个被返回的promise实例对象的结果就会成为.then返回的新promise的结果

    img

    示例1:

    const p = new Promise((resolve, reject) => {
    	reject('123');
    })
    const d = p.then((value) => {
    	console.log("成功")
    },(reason) => {
    console.log("失败",reason)
    })
    console.dir(d)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    const p = new Promise((resolve, reject) => {
             resolve('123');
    })
    const t = p.then((value) => {
    	console.log("成功")
    },(reason) => {
    console.log("失败")
    })
    console.dir(t)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    示例2:

    let promise2 = new Promise((resolve, reject) => {
        resolve(1)
    }).then(
        value => {
            console.log('success1',value)
            // return undefined //默认为undefined
            // return 1
            // return Promise.resolve(2)
            // return Promise.reject(3)
            // throw 4
        })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    结论:

    1、通过return 返回一个非promise的值,则新promise的状态fulfilled,值为return 的值

    2、不做任何处理(不return == return undefined),所以根据结论1新promise的状态为fulfilled,值为undefined

    3、通过throw主动抛出错误或者代码出现错误,则promise的状态为rejected,值为throw的值

    4、通过return 返回一个promise对象,则新promise就是return的promsie

    可根据示例2代码,挨个取消注释并在控制台打印promise2查看

  • 相关阅读:
    智慧新能源电站远程监控系统总体设计
    CentOS 7:服务器环境搭建
    PostCSS概述
    Java 高频疑难问题系列一
    2022-09-14 C++并发编程(二十二)
    IT运维管理平台助力企业打造监、管、控一体化
    深度学习(十四)——优化器
    代码中统一异常如何处理,才能让代码更清晰
    RFID超高频终端深圳厂家 源头供应 提供SDK 支持二次开发
    mysql MVCC多版本并发控制
  • 原文地址:https://blog.csdn.net/weixin_43862596/article/details/126727491