在JavaScript中,你可以通过2种方式访问一个承诺的履行值或拒绝原因。
A) 在promise.then(fn, fn) 上使用2个回调。
javascript
promise
.then(success, error);
B) 或者使用一连串的promise.then(fn).catch(fn) 。
javascript
promise
.then(success)
.catch(error);
这2种方法有什么区别吗?让我们来看看!
1.什么是相同的
让我们考虑一下我们要使用的回调。
javascript
function success(value) {
console.log('Resolved: ', value);
}
function error(err) {
console.log('Error: ', err);
}
success() 函数将在履行时被调用,而 在拒绝时被调用。error()
在大多数情况下,两种方法的工作方式是一样的:如果promise 解决成功,那么在两种方法中都会调用success 。
javascript
Promise.resolve('Hi!')
.then(success, error);
// Logs 'Resolved: Hi!'
Promise.resolve('Hi!')
.then(success)
.catch(error);
// Logs 'Resolved: Hi!'
否则,在拒绝的情况下,error 回调被调用。
javascript
Promise.reject('Oops!')
.then(success, error);
// Logs 'Error: Oops!'
Promise.reject('Oops!')
.then(success)
.catch(error);
// Logs 'Error: Oops!'
在上面的例子中,两种方法的行为都是一样的。
2.2.有什么区别
当已解决的承诺的success() 回调返回一个被拒绝的承诺时,就会看到区别。这可能发生在解析的值无效的时候。
让我们修改成功回调以返回一个拒绝的承诺。
javascript
function rejectSuccess(invalidValue) {
console.log('Invalid success: ', invalidValue);
return Promise.reject('Invalid!');
}
现在让我们在两种方法中使用rejectSuccess 。
javascript
Promise.resolve('Zzz!')
.then(rejectSuccess, error);
// Logs 'Invalid success: Zzzzz!'
Promise.resolve('Zzz!')
.then(rejectSuccess)
.catch(error);
// Logs 'Invalid success: Zzzzz!'
// Logs 'Error: Invalid!'
Promise.resolve('Zzz!').then(rejectSuccess, error) 只调用 ,即使 返回一个拒绝的承诺。rejectSuccess rejectSuccess error 回调不被调用。
Promise.resolve('Zzz!').then(rejectSuccess).catch(error) 调用 ,因为承诺已被解决。但是 返回一个被拒绝的承诺,--它被 启动,并且rejectSuccess rejectSuccess .catch(error) error 回调被调用。这就是区别。
3.何时使用
这可能是有用的,例如,当你执行一个获取请求来获取一个项目的列表,但该列表必须至少有一个项目。
因此,如果列表是空的,你可以简单地拒绝该列表。
javascript
import axios from "axios";
axios("/list.json")
.then(response => {
`const list = response.data;`
`if (list.length === 0) {`
`return Promise.reject(new Error("Empty list!"));`
`}`
`return list;`
})
.catch((err) => {
`console.log(err);`
});
在上面的例子中,.catch(error) 会捕捉到请求错误和空列表错误。
4.总结
promise.then(success, error) 和promise.then(success).catch(error) 这两个表单之间的主要区别是,如果success 的回调返回一个拒绝的承诺,那么只有第二个表单会捕捉到这个拒绝。