Promise 链的返回值

基础知识

  1. 如何让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中被捕获
});
  1. .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链中三种返回结果处理方式

  1. 返回 普通对象|值(非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
})
  1. 返回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。
  });
  1. 代码报错或者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);
    });
  }
}
相关推荐
摸着石头过河的石头31 分钟前
Service Worker 深度解析:让你的 Web 应用离线也能飞
前端·javascript·性能优化
不爱吃糖的程序媛1 小时前
Electron 如何判断运行平台是鸿蒙系统(OpenHarmony)
javascript·electron·harmonyos
Hilaku1 小时前
我用AI重构了一段500行的屎山代码,这是我的Prompt和思考过程
前端·javascript·架构
Cxiaomu2 小时前
React Native App 自动检测版本更新完整实现指南
javascript·react native·react.js
掘金安东尼2 小时前
前端周刊第439期(2025年11月3日–11月9日)
前端·javascript·vue.js
起这个名字3 小时前
微前端应用通信使用和原理
前端·javascript·vue.js
鹏多多3 小时前
Web使用natapp进行内网穿透和预览本地页面
前端·javascript
钱端工程师4 小时前
uniapp封装uni.request请求,实现重复接口请求中断上次请求(防抖)
前端·javascript·uni-app
茶憶4 小时前
uni-app app移动端实现纵向滑块功能,并伴随自动播放
javascript·vue.js·uni-app·html·scss
茶憶4 小时前
uniapp移动端实现触摸滑动功能:上下滑动展开收起内容,左右滑动删除列表
前端·javascript·vue.js·uni-app