小白必懂的Promise解析

Promise是什么?

Promise 是一种在JavaScript中用于处理异步操作的编程模式。它表示一个尚未完成但预计在未来某个时刻完成的操作的结果。

为什么要用Promise?

Promise允许我们以更简洁、易读的方式处理异步操作,避免了传统的回调地狱(callback hell)问题。

Promise的状态?

  1. pending(待定):初始状态,既不是fulfilled,也不是rejected。

  2. fulfilled(已完成):表示异步操作已成功完成。

  3. rejected(已拒绝):表示异步操作失败。

Promise的特点?

  1. Promise对象是不可变的,一旦创建,其状态就不能再被改变。

  2. Promise状态只能从pending变为fulfilled或rejected,不能逆向改变,且只能改变一次。

  3. Promise允许我们将成功和失败的处理函数分开,增加代码的可读性。

Promise的缺点?

  1. 无法取消:一旦创建了 Promise,就无法取消它。这可能导致在某些情况下,不再需要结果的异步操作仍然在执行。

  2. 总是异步:Promise 的回调总是异步执行,即使操作已经完成。这可能会导致一些意外的行为,特别是在执行顺序敏感的情况下。

  3. 调试困难:由于 Promise 的链式调用和异步特性,调试 Promise 可能比调试同步代码更具挑战性。错误堆栈可能不够清晰,难以确定问题出在哪里。

Promise的方法?

1. 创建Promise对象
  • 通过 new Promise((resolve,reject) => { } ) 创建一个Promise对象
  • 参数为一个执行器函数,执行器函数接受两个参数:resolve和reject。
  • 成功时调用resolve函数并传递结果,失败时调用reject函数并传递原因。
javascript 复制代码
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('completed.');
  }, 2000);
});
2. 链式调用
  • .then() 方法处理fulfilled状态
    接受一个回调函数作为参数时,代表的是resolve结果
    接受两个回调函数作为参数时,第一个参数为resolve结果,第二个参数为reject结果
    当Promise状态变为fulfilled时调用。
javascript 复制代码
两个参数的then
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('completed.');
  }, 2000);
});

promise.then(
  result => {
    console.log(result); // 在异步操作成功时被调用
  },
  error => {
    console.error(error); // 在异步操作失败时被调用
  }
);
  • .catch() 方法处理rejected状态,接受一个回调函数作为参数,代表的是reject结果
    当Promise状态变为rejected时调用。
typescript 复制代码
一个参数的then
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('completed.'); 
  }, 2000);
});

promise.then(result => {
    console.log(result);
  })
  .catch(error => {
    console.error(error);
  });
3. Promise.all(木桶原理)

接受一个Promise可迭代对象(如数组)作为参数

  • 当所有Promise都变为fulfilled状态时返回一个新的Promise,其值为所有Promise结果的数组。
  • 如果有任意一个Promise变为rejected状态,则返回的Promise也变为rejected,且返回原因是第一个rejected的Promise的原因。
  • 适用场景当需要等到多个异步操作都完成后才执行下一步操作时,可以使用 Promise.all 保证多个异步操作都完成并返回结果
typescript 复制代码
// Promise.all 成功示例
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 1 OK');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 2 OK');
  }, 500);
});

Promise.all([promise1, promise2])
  .then(results => {
    console.log(results); // ['Promise 1 OK', 'Promise 2 OK']
  })
  .catch(error => {
    console.error(error);
  });
typescript 复制代码
// Promise.all 失败示例
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 1 OK');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('Promise 2 failed');
  }, 500);
});

Promise.all([promise1, promise2])
  .then(results => {
    console.log(results); 
  })
  .catch(error => {
    console.error(error); //报错 Promise 2 failed
  });
4. Promise.race(赛跑)
  • 接受一个Promise可迭代对象(如数组)作为参数
  • 返回一个新的Promise,其状态和结果与第一个完成(无论是fulfilled还是rejected)的Promise相同。
  • 适用场景当需要在多个异步操作中只获取最快的结果时,可以使用 Promise.race 获取最先解决的 Promise 对象的结果
typescript 复制代码
// Promise.race 示例
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 1');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('Promise 2');
  }, 500);
});

Promise.race([promise1, promise2])
  .then(result => {
    console.log(result); // Promise 2
  })
  .catch(error => {
    console.error(error);
  });
5. Promise.finally(兜底清除)
  • 接收一个回调函数作为参数,该回调函数在 Promise 对象解决或拒绝后都会被调用。
  • 返回一个新的 Promise 对象,与原始 Promise 对象的状态和值相同,但在 finally 回调函数被调用之前不会被resolve或reject。
  • 适用场景:当需要在 Promise 对象被resolve或reject后执行一些清理操作(如关闭文件、释放资源等)时
typescript 复制代码
// Promise.finally 示例
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Success');
  }, 1000);
});

promise
  .then(result => {
    console.log(result); // 'Success'
  })
  .catch(error => {
    console.error(error);
  })
  .finally(() => {
    console.log('Cleaning up...');
  });

Promise中resolve和fulfilled区别?

我认为resolve跟最终状态fulfilled无关

Promise.resolve() 并不一定使promise最终是fulfilled

就比如说,PromiseA内部会resolve一个PromiseB,当PromiseA resolve时,并没有fulfilled,而仅仅只是resolve,只有当PromiseB也resolve后,才算真的fulfilled

相关推荐
qq_1777673713 小时前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos
烬头882113 小时前
React Native鸿蒙跨平台应用实现了onCategoryPress等核心函数,用于处理用户交互和状态更新,通过计算已支出和剩余预算
前端·javascript·react native·react.js·ecmascript·交互·harmonyos
程序员清洒14 小时前
Flutter for OpenHarmony:Text — 文本显示与样式控制
开发语言·javascript·flutter
雨季66615 小时前
Flutter 三端应用实战:OpenHarmony 简易“动态内边距调节器”交互模式深度解析
javascript·flutter·ui·交互·dart
天人合一peng15 小时前
Unity中button 和toggle监听事件函数有无参数
前端·unity·游戏引擎
会飞的战斗鸡15 小时前
JS中的链表(含leetcode例题)
javascript·leetcode·链表
方也_arkling16 小时前
别名路径联想提示。@/统一文件路径的配置
前端·javascript
毕设源码-朱学姐16 小时前
【开题答辩全过程】以 基于web教师继续教育系统的设计与实现为例,包含答辩的问题和答案
前端
qq_1777673716 小时前
React Native鸿蒙跨平台剧集管理应用实现,包含主应用组件、剧集列表、分类筛选、搜索排序等功能模块
javascript·react native·react.js·交互·harmonyos
qq_1777673716 小时前
React Native鸿蒙跨平台自定义复选框组件,通过样式数组实现选中/未选中状态的样式切换,使用链式调用替代样式数组,实现状态驱动的样式变化
javascript·react native·react.js·架构·ecmascript·harmonyos·媒体