promise理解及使用

在这里插入图片描述

1、对promise的理解

promise可以看做是一个容器,里面有个未来才会结束的事件(异步操作),并会在该事件结束后返回一个结果,我们需要等待他返回结果后再进行后续一些列的逻辑或流程化的操作

2、用法(Promise对象是一个构造函数,用来生成Promise实例)

1、状态不受外界影响
2、有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。
3、Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected
4、promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。其中resolve是成功后的后调,并通过resolve将成功后的数据传出,在.then中获取,reject是失败后的后调,并通过reject将错误信息传出去,在catch中获取错误信息,例子如下:我们使用setTimeout模拟异步操作

// 需求:我们需要在一个接口中得到数据num,并根据接口回调的成功与否来决定后续的流程,接口失败抛出异常,接口成功,继续后续流程
// 我们通过手动的if判断随机数num是否大于5来决定promise抛出的是成功resolve还是失败reject
function timeout() {
  return new Promise(function(resolve, reject) {
    const time = setTimeout(() => {
      const num = Math.floor(Math.random() * 10 + 1)
      console.log('++++', num)
      if (num > 5) {
        resolve(num)
      } else {
        const msg = 'num小于5,条件不成立,抛错'
        reject(msg)
      }
    }, 3000)
  })
}
timeout().then(res => {
  console.log(res, 'promise结束了') // ++++ 6  5 promise结束了
}).catch(error => {
  console.log(error) // ++++ 2  num小于5,条件不成立,抛错
})
// 解析如下:
// promise.then检索到promise的成功回调时,则执行console.log(res, 'promise结束了'),++++ 6  5 promise结束了
// 并打印res(即resolve中传出来的参数num)和promise结束了
// 如果该peomise抛出了reject,则会执行.catch(),并执行console.log(error),
// error是promise中的reject抛出的msg,所以会打印++++ 2  num小于5,条件不成立,抛错

在这里插入图片描述

3、.then接收两方法可以接受两个回调函数作为参数。

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

timeout().then(function(res){
    console.log('res', res)  // 成功的回调
},function(err){
    console.log('err', err)  // 失败的回调
})
4、调用resolvereject并不会终结 Promise 的参数函数的执行。

因为立即 resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务,
因为promise的主要任务是用于跑一些异步操作,并返回最终的状态为终极目标,建议resolve或者reject后不要写逻辑代码,保险起见,可以使用return,例如: return resolve()或者 return reject()

const promise = new Promise((resolve, reject) => {
    resolve(1)
    console.log('resolve或reject之后执行的')
})
promise.then(res => {
    console.log(`结束了,打印的res结果是${res}`)
}) // 解析如下:
// promise建立后会立即执行,但resolve并不会阻止后续的代码运行,
// 所以先打印的resolve或reject之后执行的,
// 当promise结束运行抛出状态后,也就是then之后,在打印的结束了,打印的res结果是1 如下图所示;

在这里插入图片描述

5、promise的链式操作(Promise.prototype.then(),catch可以捕获任何一个promise中的异常)

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法
第二个及以后的then接收的res是上一个then中return的一个新promise,如果没有return,会默认return一个promise,并且resolve为空,即:resolve())

const p1 = () => { 
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            console.log('1')
            resolve()
        },2000)
    })
}
p1().then(()=> {
    console.log('2')
}).then(() =>{
    console.log('3')
}) // 打印结果如下:
// 1  2  3 
const p1 = () => { 
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            console.log('1')
            resolve('+++++666')
        },2000)
    })
}
p1().then((res)=> {
    console.log('2', res)
}).then((res) =>{
    console.log('3', res)
}) // 打印结果如下:
// 1                p1()会立即执行,打印1,并返回resolve的结果,传出参数‘+++++666’
// 2 +++++666       .then接收到resolve传出的参数,并使用形参res来接收,最后打印了2 +++++666
// 3 undefined      上边的.then只是抛出了一个promise,但并未带出resolve的参数, 所以下边的.then并拿不到参数
// 修改如下:
p1().then((res)=> {
    console.log('2', res)
    return Promise.resolve('then之后return一个新的promise,并返回resolve')
}).then((res) =>{
    console.log('3', res)
}) 
// 1
// 2 +++++666
// 3 then之后return一个新的promise,并返回resolve
// 修改如下: 
p1().then((res)=> {
    console.log('2', res)
    return Promise.reject('报错了')
}).then((res) =>{
    console.log('3', res)
}).catch((err) => {
    console.log('err', err)
})
// 1
// 2 +++++666
// err 报错了
// 解析如下:前两步同上,没有区别
// 当p1().then中抛出promise,并且是抛出错误reject,所以第二个.then停止
// 进入.catch并处理,使用形参err接收reject传出的错误结果,随后打印字符串err和抛出来的异常结果“报错了”

多个promise的链式操作,catch可以捕获任意一个promise中的异常

const p1 = () => { 
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            console.log('1')
            resolve('666')
        },2000)
    })
}
const p2 = () => { 
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            console.log('2')
            resolve('777)
        },2000)
    })
}
p1().then((res) =>{
    console.log('3', res)
    return p2()
}).then((res) => {
    console.log('4', res)
}).catch((err) => {
    console.log(err)
})  // 打印结果如下:
// 1
// 3 666
// 2 
// 4 777


// 修改如下:
const p1 = () => { 
    return new Promise((resolve,reject) => { 
        setTimeout(()=>{ 
            console.log('1')
            reject('我在第一个promise中就报错了')
        },2000)
     }) 
}
const p2 = () => { 
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            console.log('2')
            resolve()
        },2000)
     })
} 
p1().then((res) =>{ 
    console.log('3') 
    return p2() 
}).then((res) => { 
    console.log('4') 
}).catch((err) => {
    console.log(err)
}) // 1   我在第一个promise中就报错了
// 解析如下:
// 当p1()开始的时候,进入p1,打印1 打印文1之后抛错reject,并抛出结果“我在第一个promise中就报错了”
// 因为p1抛错,所以p1().then()停止,进入.catch()中,然后使用形参err接收reject抛出的错误结果,并打印
6、Promise.all()用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]); // Promise.all()方法接受一个数组作为参数

Promise.all()同样两个回调函数,then和catch,当所有的(p1、p2、p3)返回resolve时,Promise.all会调用then方法,使用形参res来接收每一个promise实例返回的resolve,并存在数组中,当有一个promise为reject时,则会执行catch方法,并通过形参err接收错误信息

const p1 = () => { 
    return new Promise((resolve,reject) => { 
        setTimeout(()=>{ 
            resolve('111')
        },2000)
     }) 
}
const p2 = () => { 
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            resolve('222')
        },2000)
     })
} 
Promise.all([p1(),p2()]).then(res => {
    console.log('00000', res)
}) // 打印如下:
// 00000 ['111', '222']  
// 每个(p1、p2)都是resolve,所以Promise.all执行then,并把每个resolve放在数组中,使用形参res接收,并打印[111,222]
// 当有一个为reject时,Promise.all就会执行catch,示例如下:
const p1 = () => {
    return new Promise((resolve,reject) => { 
        setTimeout(()=>{ 
            reject('111')
        },2000)
     }) 
}
const p2 = () => { 
    return new Promise((resolve,reject) => {
        setTimeout(()=>{
            resolve('222')
        },2000)
     })
} 
Promise.all([p1(),p2()]).then(res => {
    console.log('00000', res)
}).catch(err => {
    console.log('err', err)
})
// 00000 111 p1抛出异常并把数据111抛出,Promise.all执行catch方法,通过形参err接收111并打印
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值