浅析Promise的方法Promise.all()、Promise.race()

118 阅读3分钟

Promise简介

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理,解决了回调地狱。

Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Fulfilled(已完成)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从 Pending 变为 Fulfilled 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

Promise.all 和 Promise.race

Promise对象提供了许多实用的方法,例如 Promise.all 和 Promise.race 是两种非常实用的方法,在我们的日常开发中某些场景时使用特别方便。
1.Promise.all(array): 其中array是多个Promise对象实例,只有当里面的所有实例有返回值时,Promise.all才会有返回值(其值是一个数组)。在实际开发中,例如请求c的参数需要依赖请求a请求b的返回值时,我们就可以利用Promise.all让二者并行去请求。而不需要分别让二者的请求变得同步。基本使用方法如下:

function player(name) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(name)
            // reject('出错了')
        }, Math.random() * 1000)
    })
}

let p1 = player('库里')
let p2 = player('杜兰特')
let p3 = player('乔治')

Promise.all([p1,p2,p3]).then(res => {
    console.log(res)  //会输出一个数组['库里', '杜兰特', '乔治']
}).catch(err => {
    console.log(err)
})

2.Promise.race(array): 其中array是多个Promise对象实例,就是race这个单词的意思一样,意思是哪个跑得快,哪个就输出,当只要有一个Promise实例有返回值时,Promise.race的返回值就是这个值。通常我们再http请求时,做超时判断时可以这样使用,设置一个定时器,当定时器时间到了时就在UI上提醒请求超时。基本使用如下:

function player(name) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(name)
            // reject('出错了')
        }, Math.random() * 1000)
    })
}

let p1 = player('库里')
let p2 = player('杜兰特')
let p3 = player('乔治')

Promise.race([p1,p2,p3]).then(res => {
    console.log(res) //会随机输出库里、杜兰特、乔治其中一个值
}).catch(err => {
    console.log(err)
})