目录
这篇主要讲一下promise的类方法的基本使用,至于promise的基本使用这里就不赘述了,之前也有手写过promise、实现了promise的核心逻辑。其实我们平时用promise也挺多的,不过又出现了两个新的语法(es11,es12新增了两个),所以这篇就简单说一下,也挺简单
1. all
promise.all方法我们可以传入一个数组参数,数组中可以放多个promise,它会等所有的promise的状态都为fulfilled时,来获取最终的结果,它会把所有每个promise resolve的结果,放在一个数组中,且结果的顺序和我们传入的数组参数中的promise保持一直(跟时间无关)
const p1 = new promise((resolve, reject) => { const obj = { data: '11111' } settimeout(() => { resolve(obj) }, 3000) }) const p2 = new promise((resolve, reject) => { const obj = { data: '22222' } settimeout(() => { resolve(obj) }, 2000) }) const p3 = new promise((resolve, reject) => { const obj = { data: '33333' } settimeout(() => { resolve(obj) }, 1000) }) promise.all([p1, p2, p3]).then(result => { console.log(result) }).catch(err => { console.log('err:', err) })
上面代码会在3s后在then方法中拿到最终的结果如下:
但是all方法是有个缺陷的,当有其中一个promise变成rejected状态时,新promise就会立即变成对应的reject状态,也就是只能在catch中捕获到错误,其他fulfilled状态的值我们是拿不到的。因此有了allsettled方法
2. allsettled
allsettled是在es11(2020)中添加的新的api,promise.allsettled
该方法会在所有的promise都有结果时(无论是fulfilled,还是rejected)都会在then方法中拿到我们的最终的结果:
const p1 = new promise((resolve, reject) => { const obj = { data: '11111' } settimeout(() => { resolve(obj) }, 3000) }) const p2 = new promise((resolve, reject) => { const obj = { data: '22222' } settimeout(() => { reject(obj) }, 2000) }) const p3 = new promise((resolve, reject) => { const obj = { data: '33333' } settimeout(() => { resolve(obj) }, 1000) }) promise.allsettled([p1, p2, p3]).then(result => { console.log(result) }).catch(err => { console.log('err:', err) })
我们传入了三个promise,在2s的时候我们的p2就reject拒绝了,但是我们同样可以拿到结果,但是这个result结果数组结构有点儿变化,我们看下打印结果:
我们可以看到allsettled的结果是一个数组,数组中存放着每一个promise的结果,并且是对应一个对象的;这个对象中包含status状态,以及对应的value值
3. race
race是竞技、赛跑的意思,也就是谁先有结果我就要谁,这个result拿到的结果就不是一个数组了,而是最快的一个promise resolve出来的结果
const p1 = new promise((resolve, reject) => { const obj = { data: '11111' } settimeout(() => { resolve(obj) }, 3000) }) const p2 = new promise((resolve, reject) => { const obj = { data: '22222' } settimeout(() => { resolve(obj) }, 2000) }) const p3 = new promise((resolve, reject) => { const obj = { data: '33333' } settimeout(() => { resolve(obj) }, 1000) }) promise.race([p1, p2, p3]).then(result => { console.log(result) }).catch(err => { console.log('err:', err) })
看下控制台的打印:
因为p3用时最短,最快,所以result拿到的就是p3resolve出的结果值,但是如果最快的那个reject了呢我们看一下:
const p1 = new promise((resolve, reject) => { const obj = { data: '11111' } settimeout(() => { resolve(obj) }, 3000) }) const p2 = new promise((resolve, reject) => { const obj = { data: '22222' } settimeout(() => { reject('出错了~~~') }, 500) }) const p3 = new promise((resolve, reject) => { const obj = { data: '33333' } settimeout(() => { resolve(obj) }, 1000) }) promise.race([p1, p2, p3]).then(result => { console.log(result) }).catch(err => { console.log('err:', err) })
我们修改一下代码,将p2时间设置为0.5s,且是rejected的状态,我们再看下打印结果:
直接就会被catch捕获了,这样看来,如果最快的那个状态为rejected状态的话,那我们后面的resolve的状态也拿不到值了。如果我们想拿到最快的fulfilled状态的值,也就是如果前面有reject的,我们就忽略掉,接着等待下一个resolve的,怎么做呢,这就有了any方法
4. any
const p1 = new promise((resolve, reject) => { const obj = { data: '11111' } settimeout(() => { resolve(obj) }, 3000) }) const p2 = new promise((resolve, reject) => { const obj = { data: '22222' } settimeout(() => { reject('出错了~~~') }, 500) }) const p3 = new promise((resolve, reject) => { const obj = { data: '33333' } settimeout(() => { resolve(obj) }, 1000) }) promise.any([p1, p2, p3]).then(result => { console.log(result) }).catch(err => { console.log('err:', err) })
还是上一次的代码,我们把方法改为any,再看一下打印结果:
我们在1s后就会拿到p3 resolve的结果, 那个p2 reject的就忽略掉了,那如果我们所有的promise都是rejected状态时它会怎么做呢?我们看一下:
const p1 = new promise((resolve, reject) => { settimeout(() => { reject('出错了111~~~') }, 3000) }) const p2 = new promise((resolve, reject) => { settimeout(() => { reject('出错了222~~~') }, 500) }) const p3 = new promise((resolve, reject) => { settimeout(() => { reject('出错了333~~~') }, 1000) }) promise.any([p1, p2, p3]).then(result => { console.log(result) }).catch(err => { console.log('err:', err, err.errors) })
我们看下打印结果:
它就会走catch了,并且打印出了错误信息,其中的 err.errors中会有我们reject传递的错误信息,err是它内部封装的错误提示