promise使用及方法

本文介绍了Promise,它是异步编程及回调地狱的解决方案,有pending、fulfilled和rejected三种状态,由异步操作结果决定。同时指出其缺点,如无法取消、不设回调内部错误不反应到外部等,还列举了基本案例及Promise的多种方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

promise
是异步编程及回调地狱的一种解决方案,
有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

  • 基本案例
//  这里我就使用setTimeout 模拟ajax
  let name = new Promise((resolve,reject)=>{
      setTimeout(function(){
        // let name = '张三'  // 请求成功拿到数据
        let name = null  // 请求失败
        if (name){
          resolve(name); // 传递成功结果,改变为fulfilled状态
        } else {
          reject('获取失败!') // 传递成功结果,改变为rejected状态
        }      
      },1000)
    })
  console.log(name)
  name.then(res=>{ // then(callback(res,err)) 
    console.log(res)
  })
  .catch(err=>{ // 失败回调函数
    console.log(err)
  })
  .finally(()=>{
    console.log('不管成功或者失败都会执行!')
  })
  • 案例二(解决回调地狱)
  • 需求:三级联动,查找下一级需要上一级的id,通过接口实现
  // 不使用promise
  function getProvince(){
    let cityStr = ''
    setTimeout(()=>{ // 请求拿到省
      cityStr+='山西省'
      setTimeout(()=>{  // 请求拿到市
          cityStr+='太原市'
          setTimeout(()=>{ // 请求拿到区
              cityStr+='小店区'
              console.log(cityStr)
              // 像这种一层一层嵌套的叫做回调地狱,如果嵌套层数越多,阅读和维护就变的异常困难
            },500)
        },500)
    },500)
  }
  getProvince() 

  // 使用promise
  let p1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
      // resolve('山西省')
      reject('省错误')
    },1000)
  })
  let p2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
      // resolve('太原市')
      reject('市,错误')
    },2000)
  })
  let p3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
      resolve('小店区')
    },3000)
  })
  p1.then(res=>{
    console.log('省:'+res)
    return p2
  }).then(res=>{
    console.log('市:'+res)
    return p3
  }).then(res=>{
    console.log('区:'+res)
  }).catch(err=>{// 中途如有错误,那么就会抛出当前错误,并停止执行
    console.log(err)
  }) // 我们发现,看起来解决了无限嵌套的问题,但是代码量带多了,那么我们换一种思路实现
  • 改进后的promise
  // 使用promise,改进后
  function getPromise(params){ // 封装请求
    return new Promise((resolve,reject)=>{
      setTimeout(()=>{  // 表示请求
        resolve(params)
        // if(params === '市的接口'){
        //   reject('市级,获取失败!')
        // }
      },1000)
    })
  }
  getPromise('省的接口').then(res=>{
    console.log(res)
    return getPromise('市的接口')
  }).then(res=>{
    console.log(res)
    return getPromise('区的接口')
  }).then(res=>{
    console.log(res)
  }) .catch(err=>{
    console.log('错误:'+err)
  }) // 是不是看起来简介了很多~~

Promise.all()

  /**
   * Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
   * 注意,如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。
   * */ 
  Promise.all([p1,p2,p3])
  .then(res=>{
    // all等待所有的结果成功返回后,才会执行,
    // 中途有错误,那么就会报错(当前请求的错误),没有返回值, 也就是说不会执行
    console.log(res)
  }).catch(err=>{
    console.log(err)
  })

Promise.allSettled()

/**
   * Promise.allSettled()
   * 没有catch失败回调函数
   * 一旦结束,状态总是fulfilled,返回数组对象如:
   * [
      {
          "status": "rejected",
          "reason": "省错误"
      },
      {
          "status": "rejected",
          "reason": "市,错误"
      },
      {
          "status": "fulfilled",
          "value": "小店区"
      }
    ]
   * 我们可以根据 status 状态来 来输出原因!
  */
  Promise.allSettled([p1,p2,p3])
  .then(res=>{
    console.log(res)
  })

Promise.race()

  /**
   * Promise.race()
   * 多个 Promise 实例,包装成一个新的 Promise 实例
   * race(顾名思义是竞赛的意思)
   * 只要p1、p2、p3之中有一个实例率先返回,那个率先改变的 Promise 实例的返回值,就传递给p的回调函数
   * 注意:如果率先放回的状态为失败,那么就抛出错误,并停止执行
  */
  Promise.race([p1,p2,p3])
  .then(res=>{
    console.log(res) // 只显示第一个返回的实例值
  }).catch(err=>{
    console.log(err)
  });

Promise.any()

  /**
   * Promise.any() 
   * 跟Promise.race() 很相似,唯一区别是,就是不会因为某个 Promise 变成rejected状态而结束。
   * 注意:如果率先放回的状态为失败,那么会继续执行下一个,直到某个成功后,停止执行
  */
  Promise.any([p1,p2,p3])
  .then(res=>{
    console.log(res) // 只显示第一个返回的实例值
  }).catch(err=>{
    console.log(err)
  });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值