定义一个 openDialog 函数,有如下两种写法:
async function openDialog1() {
return doSomething()
.then(() => Promise.resolve())
.catch(() => Promise.reject());
}
async function openDialog2() {
return doSomething()
.then(Promise.resolve)
.catch(Promise.reject);
}
这两个函数看起来很相似,但它们的行为有一些细微的区别,主要体现在 .then()
和 .catch()
的写法以及它们的返回值处理上。
1. 第一个函数:openDialog1
async function openDialog1() {
return doSomething()
.then(() => Promise.resolve())
.catch(() => Promise.reject());
}
-
.then(() => Promise.resolve())
:
这里then
接受的是一个匿名函数,该函数返回Promise.resolve()
。因此,doSomething()
成功时,then
会返回一个显式的Promise.resolve()
。 -
.catch(() => Promise.reject())
:
同样,catch
也接受一个匿名函数,这个函数返回Promise.reject()
。因此,doSomething()
失败时,catch
会返回一个显式的Promise.reject()
。 -
行为总结:
- 如果
doSomething()
成功,openDialog1
将返回一个已解决的 Promise。 - 如果
doSomething()
失败,openDialog1
将返回一个被拒绝的 Promise。
- 如果
2. 第二个函数:openDialog2
async function openDialog2() {
return doSomething()
.then(Promise.resolve)
.catch(Promise.reject);
}
-
.then(Promise.resolve)
:
这里then
中传递的是Promise.resolve
本身,而不是一个返回Promise.resolve()
的函数。这意味着Promise.resolve
函数被直接传递,而不是在then
被调用时执行。潜在问题:
这样做的问题在于Promise.resolve
是一个构造函数,它会将当前传入的参数作为其参数,甚至会忽略之前doSomething()
的结果,并立即返回一个已解决的 Promise。如果doSomething()
成功执行,Promise.resolve
会被立即执行,而不会等待任何结果。 -
.catch(Promise.reject)
:
类似于then
,这里的catch
直接传递了Promise.reject
。它的行为是当doSomething()
失败时,Promise.reject
将立即执行,传入的错误也会被忽略。 -
行为总结:
- 如果
doSomething()
成功,Promise.resolve
会立即被调用并返回一个已经解决的 Promise,且不会传递doSomething()
的结果。 - 如果
doSomething()
失败,Promise.reject
会被立即调用,且传递给reject
的参数是Promise.reject
本身的行为。
- 如果
关键区别:
-
匿名函数 vs 直接传递函数引用:
openDialog1
使用了匿名函数包装Promise.resolve()
和Promise.reject()
,因此then
和catch
是在适当的时候调用这些函数。openDialog2
直接传递了Promise.resolve
和Promise.reject
,这些函数会立即执行并忽略它们接收到的参数。
-
处理结果的方式:
openDialog1
可以明确处理doSomething()
的结果(即使没有使用它),并在需要时返回显式的Promise.resolve()
或Promise.reject()
。openDialog2
的写法会导致then
和catch
在成功或失败时立即执行,不会考虑doSomething()
返回的任何结果或错误,甚至会忽略那些值。
结论:
openDialog1
是正确且可预期的写法,它正确地封装了Promise.resolve
和Promise.reject
,并且处理流程较为明确。openDialog2
可能会导致意外行为,特别是在then
和catch
中忽略了返回的值,且其行为更加不明确。