Promise笔记

promise是异步编程的解决方案

1. 什么时候用到promise?

一般情况下是有异步操作时,对其进行封装,常见的场景就是网络请求,一个网络请求完成后会传给下一个网络请求参数去继续请求,如果当这个回调比较多且数据处理比较麻烦时,就会让我们陷入回调地狱

2. 状态

等待态(Pending):比如正在进行网络请求时,或者定时器还没到时间

执行态/满足状态(Fulfilled): 当我们主动回调了resolve,就会处于该状态,并且会回调.then()

拒绝态(Rejected):当我们主动回调了reject,就会处于该状态,并且会回调.catch()

一旦Promise 被 resolve 或 reject,不能再迁移至其他任何状态(即状态 immutable)。

3. 使用

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve({ test: 1 })
        reject({ test: 2 })
    }, 1000)
}).then(data => {
    console.log(data)
}).catch(err=>{
    console.log(err)
})

new Promise时--> 保存了一些状态信息 ,执行传入的函数

在执行传入的函数时,会传入两个参数resolve, reject 本身又是函数

成功时,调用resolve,resolve被调用时,触发then,then接收的参数就是resolve传入的参数

失败时,调用reject,reject被调用时,触发catch,catch接收的参数是reject传入的参数

但是呢,then是可以传入两个参数的,第一个也就是上面的处理resolve的函数,第二个就可以是处理reject的函数,下面的写法跟上面的大同小异:

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve({ test: 1 })
        reject({ test: 2 })
    }, 1000)
}).then(data => {
    console.log(data)
}, err=>{
    console.log(err)
})

4. 链式调用

new Promise((resolve, reject) => {
    // 异步操作1
    setTimeout(() => {
        resolve('111')
    }, 1000)
}).then(data => {
    console.log(data)
    // 异步操作2,通过返回一个Promise,实现链式调用
    return new Promise((resolve, reject) => {
        resolve('222')
    })
}).then(data => {
    console.log(data)
})

可以简化:

new Promise((resolve, reject) => {
    // 异步操作1
    setTimeout(() => {
        resolve('111')
    }, 1000)
}).then(data => {
    console.log(data)
    // 异步操作2
    return Promise.resolve('222')
    // Promise.reject('失败可以调用这个')
}).then(data => {
    console.log(data)
})

还可以简化:

new Promise((resolve, reject) => {
    // 异步操作1
    setTimeout(() => {
        resolve('111')
    }, 1000)
}).then(data => {
    console.log(data)
    // 异步操作2, 直接return,其内部会自动将其包装成Promise
    return '222'
}).then(data => {
    console.log(data)
})

其中我们用throw '错误信息' 也可以手动抛出异常,在catch中可以捕获

4. Promise.finally() 

es9新增,作用类似于ajax的complete,即异步完成之后执行的代码,无论Promise运行成功还是失败

function doSomething() {
  doSomething1()
  .then(doSomething2)
  .then(doSomething3)
  .catch(err => {
    console.log(err);
  })
  .finally(() => {
    // finish here!
  });
}

5. Promise.all

经常会碰到这样的需求:我们的处理必须等待两个网络请求返回成功后才能进行,这时候我们可能会用两个变量来判断请求是否完成,但是呢,promise提供了一个方法all可以轻松的帮我们解决这个问题

它需要一个 promise 的数组作为其参数(严格来说可以是任何可迭代对象,但通常都是数组)并返回一个新的 promise。

当所有给定的 promise 都被处理并以数组的形式呈现其结果时,新的 promise 也就被 resolve。

Promise.all([
  new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
  new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
  new Promise(resolve => setTimeout(() => resolve(3), 1000))  // 3
]).then(alert); // 1,2,3 当 promise 就绪:每一个 promise 即成为数组中的一员

请注意,它们的相对顺序是相同的。即使第一个 promise 需要很长的时间来 resolve,但它仍然是结果数组中的第一个。

常见技巧是将一组作业数据映射到一个 promise 数组,然后再将它们封装进 Promise.all

6. Promise.race

语法和all()一样,但是返回值有所不同,race根据传入的多个Promise实例,只要有一个实例resolve或者reject,就只返回该结果,其他实例不再执行。(比谁先执行完,谁先执行完就用谁的结果,其它的都不再执行。race:赛跑比速度)

Promise.race([
  new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
  new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
  new Promise(resolve => setTimeout(() => resolve(3), 1000))  // 3
]).then(value=>{
  console.log(value)
}  // 3 第三个定时器先执行完成

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值