es6中Promise.all、Promise.race的实现及其用法

es6中Promise.all、Promise.race的实现及其用法

灵魂配图

在es6中,新增了Promise对象

其中有两个方法

  • Promise.all()
  • Promise.race()

都是用于将多个Promise实例包装成另一个实例

下面我会对两种方法进行介绍,以及自己使用js实现他们的方法

Promise.all()

接受一个数组,返回Promise对象:

  • let p = Promise.all([p1, p2, p3])
  • 当p1,p2,p3的状态都变为fulfilled,其p的状态才变为fulfilled。p1,p2,p3的resolve值组成数组传递给p的resolve值
  • p1,p2,p3中有一个状态变为rejected,那么p的状态变为rejected,reject的值为该promise的reject值

看个例子就懂了

如下面代码,Promise.all的resolve值为['p1', 'p2']

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let p1 = new Promise((resolve) => {
// 模拟异步
setTimeout(() => {
resolve('p1')
}, 3000)
})

let p2 = new Promise((resolve) => {
// 模拟异步
setTimeout(() => {
resolve('p2')
}, 2000)
})

Promise.all([p1, p2]).then((res) => {
console.log(res) // 输出['p1', 'p2']
})
1
2
3
4
5
6
7
8
9
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('p3')
}, 1500)
})

Promise.all([p2, p3]).then(null, (res) => {
console.log(res) // 输出'p3'
})

实现方式

代码如下,要点都写在注释里了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function PromiseAll(arr) {
// 把每个resolve的结果存放在result
let result = []
// 记录arr的长度
let length = arr.length
let curlength = 0
return new Promise((resolve, reject) => {
arr.forEach((p, index) => {
// 使用 Promise.resolve()将不是Promise对象转换为Promise对象
// 调用每一个promise对象的then方法
Promise.resolve(p).then((res) => {
// 调用之后将结果存入result
result[index] = res
curlength++
// 判断是否全部执行完毕
if (result.length === curlength) {
resolve(result)
}

// 如果出错,直接reject
}, (err) => {
reject(err)
})
});
})
}

Promise.race()

接受一个数组,返回Promise对象:

  • let p = Promise.race([p1, p2, p3])
    • 当p1,p2,p3中最先变为fulfill或者rejected的Promise对象的reject或resolve值,就为p的reject或resolve值

看个例子就懂了

下面代码p2状态更快变为fulfilled输出值为p2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let p1 = new Promise((resolve) => {
// 模拟异步
setTimeout(() => {
resolve('p1')
}, 3000)
})

let p2 = new Promise((resolve) => {
// 模拟异步
setTimeout(() => {
resolve('p2')
}, 2000)
})

Promise.race([p1, p2]).then((res) => {
console.log(res) // 'p2'
})

实现方式

该方法要比all简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function PromiseRace(arr) {
return new Promise((resolve, reject) => {
arr.forEach((p, index) => {
// 使用 Promise.resolve()将不是Promise对象转换为Promise对象
// 调用每一个promise对象的then方法
// 之后直接resolve或reject
Promise.resolve(p).then(result => {
resolve(result)
}, (err) => {
reject(err)
})
})
})
}

总结

以上就是Promise.all和Promise.race的介绍以及源码实现。

还是比较简单,不过有个注意的点就是使用Promise.resolve(p)将非Promise对象转为Promise对象,这样才能调用then方法

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×