基础知识
- 如何让
promise
拒绝
- 直接
reject
- 代码出错等效于
reject
throw
等效于代码出错
js
const p1 = new Promise(function(resolve, reject){
reject(13); // 1. 创建一个立即拒绝的Promise
// aaa(); // 2. 代码出错
// throw(13); // 3. 直接throw
});
p1.then(function(value){
console.log(value + 1);
}).catch(function(err){
console.error(err); // 三种方式一样都会在第一个catch中被捕获
});
.then(resovleFn, rejectFn)
等效于.then(resolveFn).catch(rejectFn)
,显然后者更优雅,下面代码全部选择后者
js
// .then(resovleFn, rejectFn)方式
const p1 = new Promise(function(resolve, reject){
reject(13); // 创建一个立即拒绝的Promise
});
p1.then(function(value){
console.log(value + 1);
}, function(err){
console.error(err); // 13
});
js
// .then(resolveFn).catch(rejectFn)方式
const p1 = new Promise(function(resolve, reject){
reject(13); // 创建一个立即拒绝的Promise
});
p1.then(function(value){
console.log(value + 1);
}).catch(function(err){
console.error(err); // 13
});
promise链中三种返回结果处理方式
- 返回 普通对象|值(非Promise)
在then或者catch中返回 普通对象|值, 都会执行下一个then, 并将返回值作为实参传入
js
const p1 = new Promise(function(resolve, reject){
resolve(13); // 创建一个立即完成的Promise
});
p1.then(function(value){ // 13
return value + 1; // 14
}).then(function(value){ // 14
return value + 1; // 15
}).then(function(value){ // 15
console.log(value)
}).then(function(value){
console.log(value) // undefined
})
js
const p1 = new Promise(function(resolve, reject){
reject(13); // 创建一个立即拒绝的Promise
});
p1.then(function(value){
return value + 1;
}).catch(function(value){ // 13
return value + 1; // 14
}).then(function(value){ // 14
console.log(value); // 14
})
- 返回Promise对象
在then或者catch中返回Promise对象, 这个Promise对象会接管后面的链, 具体执行什么将取决于这个Promise对象是resovle还是reject,参见基础知识1
js
const p1 = new Promise(function(resolve, reject){
resolve("promise-1"); // 创建一个立即完成的Promise
});
const p2 = new Promise(function(resolve, reject){
resolve("promise-2"); // 创建一个立即完成的Promise
});
p1.then(function(value){ // value === "promise-1"
return p2;
}).then(function(value){ // value === "promise-2"
return value + "-r";
}).then(function(value){ // value === "promise-2-r"
console.log(value);
})
js
const p1 = new Promise(function(resolve, reject){
resolve("promise-1"); // 创建一个立即完成的Promise
});
const p2 = new Promise(function(resolve, reject){
reject("promise-2"); // 创建一个立即拒绝的Promise
});
p1.then(function(value){ // value === "promise-1"
return p2;
}).then(function(value){
// 因为p2已接管链, 并已拒绝,不会走这里,会走下一个catch
return value + "-r";
}).catch(function(err){
console.error(err); // "promise-2"
})
Promise对象允许你为异步操作的成功值或失败原因(reason)注册回调函数。你可以使用.then()
方法来注册成功回调,使用.catch()
方法来注册失败回调。
当你想要先捕获错误,再在成功时继续执行操作时,你可以先调用.catch()
然后是.then()
。这样,错误会先被.catch()
捕获,之后才是.then()
中的成功回调。
如下代码,catch()
是then()
的语法糖,所以catch
后的then
语句是会执行的。以及then()
返回的是一个promise
。
js
function asyncOperation() {
return new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
// 可以改变条件来测试成功或失败的情况
let condition = true; // 改为 false 测试失败情况
if (condition) {
resolve('操作成功');
} else {
reject('操作失败');
}
}, 1000);
});
}
asyncOperation()
.catch(error => {
console.error('捕获错误:', error);
// 返回一个值以继续链式调用
return '处理过的错误信息';
})
.then(success => {
console.log('继续执行:', success);
})
.catch(error => {
console.error('再次捕获错误:', error); // catch()是then()的语法糖,所以catch后的then语句是会执行的。以及then()返回的是一个promise。
});
- 代码报错或者throw
promise链中代码报错或者主动throw,都会执行下一个catch
js
const p1 = new Promise(function(resolve, reject){
resolve("promise-1"); // 创建一个立即完成的Promise
});
p1.then(function(){
aaa(); // 1. 代码报错
// throw("my error"); // 2. 主动throw
}).catch(function(err){
console.error(err); // 两种方式都会走到这里
})
总结
可以看到,如果返回的是普通对象,将作为下次then函数的参数传入;
如果返回的是Promise对象(p2),那么p2将会接管以后的Promise链 可以假想then函数中处理如下
js
function then(resolve, reject) {
const result = resolve("xxx");
if (result instanceof Promise) {
// 如果是Promise, 直接返回
return result;
} else {
return new Promise(function(newResolve, newRejct){
// 如果是普通对象, 返回一个新的Promise, 并将结果作为参数传入
newResolve(result);
});
}
}