• promise


    1 ,背景

    Promise 是异步编程的一种解决方案,Promise 是一个对象,从它可以获取异步操作的消息

    2,特点

    (1)对象的状态不受外界影响。

    Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。

    只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态

    (2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。

    Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected

    只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)

    3,缺点

    (1)无法取消Promise,一旦新建它就会立即执行,无法中途取消。

    (2)如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

    (3)当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

    4,用法

     1 基本用法

    let p1 = () => {
          return new Promise((resolve, reject) => {
                    console.log('3秒钟后,p1函数结束');
                    setTimeout(() => {
                         //返回Promise
                        resolve(p2())
                   }, 3000)
          })
    };


    let p2 = () => {
         return new Promise((resolve,reject)=> {
                   console.log('p1结束,现在是第二个任务了!');
                  resolve({key: 2, content: "第二个任务结束"})
         })
    };


    p1().then((res) => {
        console.log(res);
        p2().then((res2) => {
              console.log(res2);
             //返回Promise
            return new Promise((resolve ,reject)=> {
                    console.log('开始第三个任务,这个任务是继续第二个的异步。');
                    setTimeout(()=>reject({key:3,content:"第三个任务报错!"}),2000)
            })
       }).catch((error)=>console.log(error));
    });

    结果:

    3秒钟后,p1函数结束   -------promise创建后立即执行

    -----  console.log(res);

    p1结束,现在是第二个任务了!

    {key: 2, content: "第二个任务结束"}

     

    ------console.log(res2);

          p1结束,现在是第二个任务了!

          {key: 2, content: "第二个任务结束"}

        --------在resolve后调用catch无效,无法抛出错误,因为状态已经改变

         开始第三个任务,这个任务是继续第二个的异步

    注意点: promise是个对象  一定要return出来, Promise对象上才有then、catch回调和  2个参数  resolve  rejecte

    let promise = new Promise(function(resolve, reject) {
      console.log('Promise');
      resolve();
    });
    
    promise.then(function() {
      console.log('resolved.');
    });
    
    console.log('Hi!');
    
    // Promise
    // Hi!
    // resolved
    

    上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出

    2 升级用法:

    a  )Promise.prototype.then() 

    then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。这两个函数都是可选的,不一定要提供。它们都接受Promise对象传出的值作为参数。

    采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

    b )Promise.prototype.catch()

    .then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

    c )  p=promise.all([a(),b()]).then().catch()  //必须一起执行且都成功,只返回第一个错误状态

    Promise.all()只有在接受的所有promise实例全部是fulfilled才会走Promise.all([p1,p2,p3]).then()方法,
    只要有其中一个promise实例是rejected,就会直接走catch方法--结束,并且catch中只会返回第一个变成rejected的promise的错误

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

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

    d)Promise.allSettled([a(),b()]).then().catch() //返回所有的请求状态  并确保请求结束

       获取所有入参的异步操作的所有结果,知道这些异步操作是否全部结束

    const resolved = Promise.resolve(42);
    const rejected = Promise.reject(-1);
    
    const allSettledPromise = Promise.allSettled([resolved, rejected]);
    
    allSettledPromise.then(function (results) {
      console.log(results);
    });
    // [
    //    { status: 'fulfilled', value: 42 },
    //    { status: 'rejected', reason: -1 }
    // ]

    e) p=promise.race([a(),b()]).then().catch() //谁跑的快用谁的值

    Promise.race() 总是返回第一个结果值(resolved/reject)那样,这个方法返回的是第一个 成功的 值。

    只要有其中一个promise实例是rejected,就会直接走catch方法--结束。并且catch中只会返回第一个变成rejected的promise的错误

       只要a,b之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

    f) Promise.any([a(),b()]).then().catch()

    只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

    g)  Promise.prototype.finally()

    promise.then(result => {···}).catch(error => {···}).finally(() => {···});
    

       不管promise最后的状态,在执行完thencatch指定的回调函数以后,都会执行finally方法指定的回调函数

     finally的回调函数不接受任何参数,方法里面的操作,是与状态无关的,不依赖于 Promise 的执行结果。

    p就是一个promise对象 才有then方法

    let p=new Promise((resolve,reject)=>{
             resolve('成功')
         })
    p.then(resolve=>{
        console.log(resolve)
    },reject=>{
        console.log(reject)
    })

     


    let p=function(){
         return new Promise((resolve,reject)=>{
                   resolve('成功')
        })
    }
    p是个函数 不是个对象 p()才是一个对象(因为有return,返回出来promise对象)


    p().then(resolve=>{
                console.log(resolve)
        },reject=>{
            console.log(reject)
    })

    var a=0;
    let p1=function(){
         return new Promise((resolve,reject)=>{
              a++;
             resolve(a);

        })
    }
    let p2=function(){
         return new Promise((resolve,reject)=>{
               a+=2;
              resolve(a);

       })
    }


    let p3=function(){
    return new Promise((resolve,reject)=>{
    a+=3;
    resolve(a);
    })
    }
    p1().then(resolve=>{
    console.log(resolve)
    return p2();//这个return是为了后面的then

    }).then(resolve=>{
    console.log(resolve)
    return p3();//这个return是为了后面的then

    }).then(resolve=>{
    console.log(resolve)

    })
    //136

  • 相关阅读:
    MessageDigest类提供MD5或SHA等加密算法
    23种设计模式之策略设计模式
    n & (n-1)
    ubuntu 常用软件配置
    minicom 没有tx 信号
    usb 驱动
    全局变量的危害
    编写安全代码:小心volatile的原子性误解
    ADB Server Didn’t ACK ,failed to Start Daemon 解决方法
    字长
  • 原文地址:https://www.cnblogs.com/fanjiawen/p/14234533.html
Copyright © 2020-2023  润新知