promise多个then、catch、finally情况

结论

先抛出结论,如下:

  1. 一个promise中,resolve、reject只会执行最先触发的那个,执行完就停止了
  2. 根据 resolve|reject 输出 then|catch、finally

  3. 多个resolve或多个reject只会执行第一个
  4. Promise立即执行函数里面的其他语句不会受到resolve、reject影响

  5. 第一次then|catch、finally执行的是promise内部的结果
  6. 第一次then|catch的参数来自promise内部的resolve、reject,finally始终无参数
  7. 第二次及以后的then一定会执行,参数来自上一个then的返回值,无返回值时参数为undefined
  8. 第二次及以后的finally一定会执行,无参数,为undefined

  9. 第二次及以后的then中如果return Error,会被下一个then作为参数输出,finally始终无参数。只会影响下一个,不会影响下下个。
  10. 第二次如果是throw Error,则会被当前紧挨着的catch语句所捕获
  11. 即:return Error只是作为一个常规的返回值(值为Error),而throw则是直接抛出异常

  12. 在then中连续写两个回调,第一个参数为then,第二个参数为catch,在then后面再写一个catch。
    如果promise是resolve,在then的第一个参数中throw Error,会被下一个catch所捕获
    如果promise是reject,在then的第二个参数中throw Error,会被下一个catch所捕获
  13. 即:then…catch可以将两个回调都写在then里面,直接写两个参数,then后面的catch会被当前其他语句的catch,只有前面的then内部抛出异常才会执行。

分析

case1_resovle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function testPromise1(val) {
return new Promise((resolve, reject) => {
resolve('成功!')
reject('失败!')
})
.then((res) => {
console.log('First then:', res)
})
.catch((err) => {
console.log('First catch:', err)
})
.finally((res) => {
console.log('First finally', res)
})
}
testPromise1()

/**
* testPromise1 执行结果:
*
* First then: 成功!
* First finally: undefined
*/

case2_reject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function testPromise2(val) {
return new Promise((resolve, reject) => {
reject('失败!')
resolve('成功!')
})
.then((res) => {
console.log('First then:', res)
})
.catch((err) => {
console.log('First catch:', err)
})
.finally((res) => {
console.log('First finally:', res)
})
}
testPromise2()

/**
* testPromise2 执行结果:
*
* First catch: 失败!
* First finally: undefined
*/

case1、case2结论:

  1. 一个promise中,resolve、reject只会执行最先触发的那个,执行完就停止了
  2. 根据 resolve|reject 先输出 promise 自己的then|catch、finall

case3_多resolve、reject

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
27
28
29
30
31
32
33
34
35
function testPromise3(val) {
return new Promise((resolve, reject) => {
console.log('testPromise1_1')
resolve('成功1!')
console.log('testPromise1_2')
reject('失败1!')
console.log('testPromise1_3')
resolve('成功2!')
console.log('testPromise1_4')
reject('失败2!')
console.log('testPromise1_5')
})
.then((res) => {
console.log('First then:', res)
})
.catch((err) => {
console.log('First catch:', err)
})
.finally((res) => {
console.log('First finally:', res)
})
}
testPromise3()

/**
* testPromise3 执行结果:
*
* testPromise1_1
* testPromise1_2
* testPromise1_3
* testPromise1_4
* testPromise1_5
* First then: 成功1!
* First finally: undefined
*/

case3结论:

  1. 多个resolve或多个reject只会执行第一个
  2. Promise立即执行函数里面的非resolve、reject语句不会受到resolve、reject影响

case4_多then、catch、finally无return

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function testPromise4(val) {
return new Promise((resolve, reject) => {
resolve('成功!')
// 以下为第一次then、catch、finally
})
.then((res) => {
console.log('First then:', res)
})
.catch((err) => {
console.log('First catch:', err)
})
.finally((res) => {
console.log('First finally:', res)
// 以下为第二次then、catch、finally
})
.then((res) => {
console.log('Second then:', res)
})
.catch((err) => {
console.log('Second catch:', err)
})
.finally((res) => {
console.log('Second finally:', res)
// 以下为第三次then、catch、finally
})
.then((res) => {
console.log('Third then:', res)
})
.catch((err) => {
console.log('Third catch:', err)
})
.finally((res) => {
console.log('Third finally:', res)
})
}
// testPromise4()
/**
* testPromise4 执行结果:
*
* First then: 成功! --- then参数值:来自promise内部的resolve参数
* First finally: undefined --- finally没有参数,为undefined
*
* Second then: undefined --- then参数值:来自第一个then的返回值,没有返回值为undefined
* Second finally: undefined --- finally没有参数,为undefined
*
* Third then: undefined --- then参数值:来自第二个then的返回值,没有返回值为undefined
* Third finally: undefined --- finally没有参数,为undefined
*/

case5_resolve引发多then、catch、finally有return

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
function testPromise5(val) {
return new Promise((resolve, reject) => {
resolve('成功!')
// 以下为第一次then、catch、finally
})
.then((res) => {
console.log('First then:', res)
return 'From first then'
})
.catch((err) => {
console.log('First catch:', err)
return 'From first catch'
})
.finally((res) => {
console.log('First finally:', res)
return 'From first finally'
// 以下为第二次then、catch、finally
})
.then((res) => {
console.log('Second then:', res)
return 'From second then'
})
.catch((err) => {
console.log('Second catch:', err)
return 'From second catch'
})
.finally((res) => {
console.log('Second finally:', res)
return 'From second finally'
// 以下为第三次then、catch、finally
})
.then((res) => {
console.log('Third then:', res)
return 'From third then'
})
.catch((err) => {
console.log('Third catch:', err)
return 'From third catch'
})
.finally((res) => {
console.log('Third finally:', res)
return 'From third finally'
})
}
// testPromise5()
/**
* testPromise5 执行结果:
*
* First then: 成功! --- then参数值:来自promise内部的resolve参数
* First finally: undefined --- finally没有参数,为undefined
*
* Second then: From first then --- then参数值:来自第一个then的返回值,没有返回值为undefined
* Second finally: undefined --- finally没有参数,为undefined
*
* Third then: From second then --- then参数值:来自第二个then的返回值,没有返回值为undefined
* Third finally: undefined --- finally没有参数,为undefined
*/

case6_reject引发多then、catch、finally有return

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
function testPromise6(val) {
return new Promise((resolve, reject) => {
reject('失败!')
// 以下为第一次then、catch、finally
})
.then((res) => {
console.log('First then:', res)
return 'From first then'
})
.catch((err) => {
console.log('First catch:', err)
return 'From first catch'
})
.finally((res) => {
console.log('First finally:', res)
return 'From first finally'
// 以下为第二次then、catch、finally
})
.then((res) => {
console.log('Second then:', res)
return 'From second then'
})
.catch((err) => {
console.log('Second catch:', err)
return 'From second catch'
})
.finally((res) => {
console.log('Second finally:', res)
return 'From second finally'
// 以下为第三次then、catch、finally
})
.then((res) => {
console.log('Third then:', res)
return 'From third then'
})
.catch((err) => {
console.log('Third catch:', err)
return 'From third catch'
})
.finally((res) => {
console.log('Third finally:', res)
return 'From third finally'
})
}
testPromise6()

/**
* testPromise6 执行结果:
*
* First catch: 失败! --- then参数值:来自promise内部的reject参数
* First finally: undefined --- finally没有参数,为undefined
*
* Second then: From first then --- then参数值:来自第一个then的返回值,没有返回值为undefined
* Second finally: undefined --- finally没有参数,为undefined
*
* Third then: From second then --- then参数值:来自第二个then的返回值,没有返回值为undefined
* Third finally: undefined --- finally没有参数,为undefined
*/

case4、case5、case6结论:

  1. 第一次then|catch、finally执行的是promise内部的结果
  2. 第一次then|catch的参数来自promise内部的resolve、reject,finally无参数
  3. 第二次及以后的then一定会执行,参数来自上一个then的返回值,无返回值为undefined
  4. 第二次及以后的finally一定会执行,无参数,为undefined

case7_new Error

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
function testPromise7(val) {
return new Promise((resolve, reject) => {
resolve('成功!')
// 以下为第一次then、catch、finally
})
.then((res) => {
console.log('First then:', res)
return new Error('From first then')
})
.catch((err) => {
console.log('First catch:', err)
return 'From first catch'
})
.finally((res) => {
console.log('First finally:', res)
return new Error('From first finally')
// 以下为第二次then、catch、finally
})
.then((res) => {
console.log('Second then:', res)
return 'From second then'
})
.catch((err) => {
console.log('Second catch:', err)
return 'From second catch'
})
.finally((res) => {
console.log('Second finally:', res)
return 'From second finally'
// 以下为第三次then、catch、finally
})
.then((res) => {
console.log('Third then:', res)
return 'From third then'
})
.catch((err) => {
console.log('Third catch:', err)
return 'From third catch'
})
.finally((res) => {
console.log('Third finally:', res)
return 'From third finally'
})
}
testPromise7()

/**
* testPromise7 执行结果:
*
* First then: 成功!
* First finally: undefined
* Second then: Error: From first then at ...
* Second finally: undefined
* Third then: From second then
* Third finally: undefined
*/

case8_throw Error

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
function testPromise8(val) {
return new Promise((resolve, reject) => {
resolve('成功!')
reject('失败!')
// 以下为第一次then、catch、finally
})
.then((res) => {
console.log('First then:', res)
// return new Error('From first then')
throw new Error('From first then')
})
.catch((err) => {
console.log('First catch:', err)
return 'From first catch'
})
.finally((res) => {
console.log('First finally:', res)
return new Error('From first finally')
// 以下为第二次then、catch、finally
})
.then((res) => {
console.log('Second then:', res)
return 'From second then'
})
.catch((err) => {
console.log('Second catch:', err)
return 'From second catch'
})
.finally((res) => {
console.log('Second finally:', res)
return 'From second finally'
// 以下为第三次then、catch、finally
})
.then((res) => {
console.log('Third then:', res)
return 'From third then'
})
.catch((err) => {
console.log('Third catch:', err)
return 'From third catch'
})
.finally((res) => {
console.log('Third finally:', res)
return 'From third finally'
})
}
testPromise8()

/**
* testPromise8 执行结果
*
* First then: 成功!
* First catch: Error: From first then at ...
* First finally: undefined
* Second then: From first catch
* Second finally: undefined
* Third then: From second then
* Third finally: undefined
*/

case7、case8结论:

  1. 第二次及以后的then中如果return Error,会被下一个then作为参数输出,finally始终无参数。只会影响下一个,不会影响下下个。
  2. 第二次如果是throw Error,则会被当前的catch语句所捕获
  3. return Error只是作为一个常规的报错返回,而throw则是直接抛出异常

case9_then回调两个参数return Error

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function testPromise9(val) {
return new Promise((resolve, reject) => {
resolve('成功!')
// 以下为第一次then、catch、finally
})
.then(
(res) => {
console.log('First then:', res)
throw new Error('From first then')
},
(err) => {
console.log('First catch1:', err)
return 'From first catch2'
}
)
.catch((err) => {
console.log('First catch2:', err)
return 'From first catch2'
})
.finally((res) => {
console.log('First finally:', res)
return new Error('From first finally')
// 以下为第二次then、catch、finally
})
.then((res) => {
console.log('Second then:', res)
return 'From second then'
})
.catch((err) => {
console.log('Second catch:', err)
return 'From second catch'
})
.finally((res) => {
console.log('Second finally:', res)
return 'From second finally'
})
}
testPromise9()

/**
* testPromise9 执行结果:
*
* First then: 成功!
* First catch2: Error: From first then at ...
* First finally: undefined
* Second then: From first catch2
* Second finally: undefined
*/

case10_then回调两个参数throw Error

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function testPromise10(val) {
return new Promise((resolve, reject) => {
reject('失败!')
})
.then(
(res) => {
console.log('First then:', res)
},
(err) => {
console.log('First catch1:', err)
// return 'From first catch2'
throw new Error('From first catch1')
}
)
.catch((err) => {
console.log('First catch2:', err)
return 'From first catch2'
})
.finally((res) => {
console.log('First finally:', res)
return new Error('From first finally')
// 以下为第二次then、catch、finally
})
.then((res) => {
console.log('Second then:', res)
return 'From second then'
})
.catch((err) => {
console.log('Second catch:', err)
return 'From second catch'
})
.finally((res) => {
console.log('Second finally:', res)
return 'From second finally'
})
}
testPromise10()
/**
* testPromise10 执行结果:
*
* First catch1: 失败!
* First catch2: Error: From first then at ...
* First finally: undefined
* Second then: From first catch2
* Second finally: undefined
*/

case11_then回调三个参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function testPromise11 (val) {
return new Promise((resolve, reject) => {
reject('失败!')
resolve('成功!')
}).then(res => {
console.log('First then:', res)
}, err => {
console.log('First catch1:', err)
}, () => {
console.log('First finally1:', err)
}).catch(err => {
console.log('First catch2:', err)
}).finally(res => {
console.log('First finally2:', res)
})
}
testPromise11()
/**
* 执行结果
*
* First catch1: 失败!
* First finally2: undefined
*/

case9、case10结论:

  1. 在then中连续写两个回调,第一个参数为then,第二个参数为catch,在then后面再写一个catch。
  2. 如果是resolve,在then的第一个参数中throw Error,会被下一个catch所捕获
  3. 如果是reject,在then的第二个参数中throw Error,会被下一个catch所捕获
  4. 即:then…catch可以将两个回调都赋给then,直接写两个参数,then后面的catch会被当前其他的catch,只有前面的then内部抛出异常才会执行。