zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    CodeForces 659F Polycarp and Hay
    CodeForces 713C Sonya and Problem Wihtout a Legend
    CodeForces 712D Memory and Scores
    CodeForces 689E Mike and Geometry Problem
    CodeForces 675D Tree Construction
    CodeForces 671A Recycling Bottles
    CodeForces 667C Reberland Linguistics
    CodeForces 672D Robin Hood
    CodeForces 675E Trains and Statistic
    CodeForces 676D Theseus and labyrinth
  • 原文地址:https://www.cnblogs.com/fanjiawen/p/14234533.html
Copyright © 2011-2022 走看看