zoukankan      html  css  js  c++  java
  • ES6中的Promise的用法总结

    第一部分、什么是Promise ? 

    Promise是ES6中提供的一个异步编程的解决方案,Promise本身是一个构造函数

    typeof Promise  //  function

    一般情况下 我们在开发中会使用 new Promise() 调用构造函数,创建一个新的Promise对象, Promise对象有两个特点

    1、对象的状态不受外界影响。Promise对象是一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。

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

    2、一旦Promise状态改变,就不会再有变化,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled 或者 从pending变为rejected。只要这两种情况发生,状态就不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的

    使用Promise的好处,就是在处理异步程序时,将异步操作队列化,按照期望的顺序执行,返回符合预期的结果,这样即使是多重异步操作,也可以方便的使用Promise进行链式调用

    3、Promise也有一些缺点。

    首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

    第二部分、循序渐进的介绍Promise的用法

    1、最简单的用法

    const  p =  new Promise((resolve, reject) => {
        // 在这里执行一个异步操作吧
        setTimeout(function(){
            console.log(1234)
            resolve(1234)
        }, 3000)
    })
    
    // 创建这个Promise之后, 3秒后 会控制台输出1234,并且3秒后得到了一个结果,异步程序返回了1234这个结果,那么
    
    p.then((res) => {
        console.log(res)
    })
    
    // 控制台会输出1234 ,promise的then方法 会再次返回一个promise,不过值默认undefined
    
    p.then((res) => {
        console.log(res)
    }).then((res)=>{
       console.log(res)    
    })
    
    // 1234, undefined

    2、reject的用法

    const p2 = new Promise((resolve, reject)=>{
        // 执行一个异步操作
        setTimeout(function(){
            console.log(1024)
            reject(1024)
        }, 3000)
    })
    
    p2.then(res=>{
        console.log(res)
    }).catch(res=>{
        console.error(res)    
    })
    
    //  3秒之后 输出错误 1024

    3、all的用法, 多个异步操作进行数组形式的返回值处理,当所有的异步都resolve时,可以执行then操作,当其中一个或多个reject时,所有的异步都会停止调用,直接返回最早发生错误的那个结果

    const pa = new Promise((resolve, reject)=>{
        setTimeout(function(){
            console.log('pa')
            resolve('pa')
        },3000)
    })
    
    const pb = new Promise((resolve, reject)=>{
       setTimeout(function(){
            console.log('pb')
            resolve('pb')
        },4000)
    })
    
    const pc = new Promise((resolve, reject)=>{
        setTimeout(function(){
            console.log('pc')
            resolve('pc')
        },5000)
    })
    
    const pd =  new Promise((resolve, reject)=>{
        setTimeout(function(){
            console.log('pd')
            reject('pd')
        },5000)
    })
    
    
    Promise.all([pa, pb, pc]).then((res)=>{
         console.log('成功' + res)
    })
    
    // 3秒后 pa  4秒后pb 5秒后 pc pd 然后输出成功pa,pb,pc
    
    Promise.all([pa, pb, pd]).then((res)=>{
        console.log('成功' + res)
    }).catch(err=>{
        console.log('失败' + err)
    })
    
    // 输出失败pd

    4、race的用法, 语法和all()一样,但是返回值有所不同,race根据传入的多个Promise实例,只要有一个实例resolve或者reject,就只返回该结果,其他实例不再执行,也就是说多个异步程序,只返回响应最快的那个异步程序,不论成功或者失败,就把最快响应的返回值返回,后面的异步程序不再执行

    const pa = new Promise((resolve, reject)=>{
        setTimeout(function(){
            console.log('pa')
            resolve('pa')
        },3000)
    })
    
    const pb = new Promise((resolve, reject)=>{
       setTimeout(function(){
            console.log('pb')
            resolve('pb')
        },4000)
    })
    
    const pc = new Promise((resolve, reject)=>{
        setTimeout(function(){
            console.log('pc')
            resolve('pc')
        },5000)
    })
    
    const pd =  new Promise((resolve, reject)=>{
        setTimeout(function(){
            console.log('pd')
            reject('pd')
        },5000)
    })
    
    const pe =  new Promise((resolve, reject)=>{
        setTimeout(function(){
            console.log('pe')
            reject('pe')
        },2000)
    })
    
    const pf =  new Promise((resolve, reject)=>{
        setTimeout(function(){
            console.log('pf')
            resolve('pf')
        },2000)
    })
    
    Promise.race([pa, pe, pf]).then(res=>{
        console.log('成功' + res)
    }).catch(res=>{
        console.log('失败' + res)
    })
    
    
    Promise.race([pd, pe]).then().catch(res=>{
        console.log('失败' + res)
    })
    
    // 2秒后 输出 失败 + pe 
    
    // 2秒后 输出 失败 +  pe

    5、resolve方法,

    Promise的resolve方法,用于将非Promise类型的对象,转为Promise对象,这样就可以调用Promise原型对象上的方法了

    Promise.resolve(x) 
    
    上面的写法等价于 
    
    new Promise(resolve => { resolve(x)})

    resolve的参数分为几种不同的情况:

    (1)没有参数,如果没有参数,这直接返回一个resolved状态的Promise对象 

    const p = Promise.resolve()
    
    相当于 
    
    const p = new Promise(resolve => {
        resolve undefined
    })
    
    p.then(res=>{
        console.log(res)
    })
    
    // 输出 undefined

    (2) 参数是一个不具有then方法的对象,或者是一个基数数据类型的值,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved,值为指定值

    const p = Promise.resolve('pro')
    
    p.then((x) =>{
        console.log(x)
    })
    
    // 输出 'pro'

    (3) 参数是一个具有then方法的对象,Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。

    const obj = {
        then: function(resolve, reject) {
            resolve(100)
        }
    }
    
    const p  = Promise.resolve(obj)
    
    p.then((res) => {
        console.log(res)
    })
    
    // 输出 100

    (4)参数是一个Promise对象,那么将原封不动的返回这个Promise对象

    6、reject方法

    reject与resolve方法基本类似,但是要注意一种情况,就是当参数是一个thenable对象时

    const thenable = {
      then(resolve, reject) {
        reject('出错了');
      }
    };
    
    Promise.reject(thenable)
    .catch(e => {
      console.log(e === thenable)
    })
    
    // true

    7、finally方法,finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

    finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。finally本质上是then方法的特例。

    const  p = new Promise((resolve, reject)=>{
        const a = Math.ceil( Math.random() * 10 )
        setTimeout(function(){
            if(a > 5) {
                resolve(a)
            } else {
                reject(a)
            }
        },3000)
    })
    
    
    p.then(res=>{
        console.log(res)
    }).catch(err=>{
        console.error(err)    
    }).finally(()=>{
       console.log('结束')
    })
    
    // 无论是resolve 还是 reject都会 执行 finally
    
    // finally的 polyfill也很简单
    
    Promise.prototype.finally = function (callback) {
      let P = this.constructor;
      return this.then(
        value  => P.resolve(callback()).then(() => value),
        reason => P.resolve(callback()).then(() => { throw reason })
      );
    };
  • 相关阅读:
    修改ESMAP中的LOGO
    AppCompatActivity隐藏顶部任务栏
    Android原生开发,view标签导致RecyleView Adapter 中报错的奇葩问题
    用UPUPW做服务器,通过thinkphp5完美搭建APP后台
    hhh
    Redis 学习
    无刷新文件上传
    mongoDB 学习
    MySQL读写分离-架构
    Mysql 通用二进制包安装
  • 原文地址:https://www.cnblogs.com/liquanjiang/p/11425902.html
Copyright © 2011-2022 走看看