javascript的Promise是什么_如何使用它处理异步【教程】

发布时间 - 2026-01-22 00:00:00    点击率:
Promise 是为解决回调地狱设计的异步抽象,不执行异步操作而管理其生命周期;构造时需传入执行器函数,内含由引擎注入的 resolve/reject;then/catch 链式调用返回新 Promise,async/await 是其语法糖但错误处理更直观。

Promise 不是回调函数的语法糖,而是为解决“回调地狱”而设计的异步抽象——它本身不执行异步操作,只管理异步操作的生命周期和状态流转。

Promise 构造函数必须传入一个执行器函数

创建 Promise 时,new Promise() 的参数是一个立即执行的函数,它接收两个参数:resolvereject。这两个函数由 JS 引擎注入,不是你定义的。

常见错误:漏写执行器、或把异步逻辑写在 new Promise() 外面导致状态无法控制:

const p = new Promise(); // ❌ 报错:需要函数参数
const p = new Promise(() => setTimeout(() => {}, 100)); // ❌ resolve/reject 没调用,Promise 永远 pending

正确写法示例:

const p = new Promise((resolve, reject) => {
  fetch('/api/data')
    .then(res => res.json())
    .then(data => resolve(data))
    .catch(err => reject(err));
});
  • 执行器函数同步运行,但内部可启动异步任务
  • resolvereject 只能触发一次,多次调用会被忽略
  • 未捕获的 reject 会触发全局 unhandledrejection 事件

then() 和 catch() 链式调用的本质是返回新 Promise

then() 总是返回一个新的 Promise,其状态取决于回调函数的返回值:

  • 返回普通值 → 新 Promise 状态为 fulfilled,值为该返回值
  • 返回另一个 Promise → 新 Promise 等待它结束,并继承其状态和值
  • 抛出异常或返回 Promise.reject() → 新 Promise 状态为 rejected

这意味着你可以安全地链式处理数据流,但也要小心隐式转换:

Promise.resolve(1)
  .then(x => x + 1)         // ✅ 返回 2,下个 then 接收到 2
  .then(x => Promise.resolve(x * 2)) // ✅ 返回 Promise{4}
  .then(x => { throw 'oops' }) // ❌ 下个 catch 才能捕获
  .catch(err => console.log(err));

注意:catch()then(null, onRejected) 的语法糖,它只能捕获前一个 Promise 的 rejection,不能跨过中间的 then() 中的同步错误(除非那个 then() 内部没处理异常)。

async/await 是 Promise 的语法糖,但错误处理方式不同

async 函数返回一个 Promise,await 后面的表达式必须是 Promise(或可转为 Promise 的值),它会暂停函数执行直到 Promise settle。

关键差异在于错误传播:

  • then().catch() 中,错误需显式传递到链尾
  • try/catch 包裹 await 能直接捕获 Promise rejection,更接近同步代码直觉

但要注意:没有 try/catchawait 会让 rejection 变成未处理异常:

async function bad() {
  const data = await fetch('/api').then(r => r.json()); // ❌ 如果 fetch 失败,这里不会 throw,但 .then 里没 catch
}

async function good() { try { const res = await fetch('/api'); if (!res.ok) throw new Error(HTTP ${res.status}); const data = await res.json(); return data; } catch (err) { console.error('请求失败:', err); } }

Promise.all() 和 Promise.race() 的陷阱

Promise.all() 在任一 Promise rejected 时就立即 reject,不等其余完成;Promise.race() 则以第一个 settle 的为准(fulfill 或 reject 都算)。

典型误用场景:

  • Promise.all([p1, p2, p3]) 发起多个请求,但其中某个失败导致全部失败 → 应改用 Promise.allSettled()(ES2025+)
  • Promise.race([fetch(), timeout()]) 做超时控制时,忘记 timeout() 必须是 Promise.reject(),否则 race 可能返回成功结果掩盖真实错误

超时控制正确写法:

function timeout(ms) {
  return new Promise((_, reject) => {
    setTimeout(() => reject(new Error('timeout')), ms);
  });
}

Promise.ra

ce([ fetch('/api'), timeout(5000) ]).catch(err => { if (err.message === 'timeout') console.log('请求超时'); else console.log('网络错误', err); });

真正难的是组合多个异步逻辑时的状态协调——比如并发限制、重试策略、缓存穿透防护,这些没法靠单个 Promise API 解决,得靠封装或工具库(如 p-limit、p-retry)。Promise 提供的是基础契约,不是银弹。


# javascript  # java  # js  # json  # go  # 回调函数  # 工具  # ai  # 异步任务  # 隐式转换 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何选择可靠的免备案建站服务器?  如何在阿里云服务器自主搭建网站?  如何用狗爹虚拟主机快速搭建网站?  手机网站制作与建设方案,手机网站如何建设?  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  微信小程序制作网站有哪些,微信小程序需要做网站吗?  Laravel怎么在Blade中安全地输出原始HTML内容  成都网站制作公司哪家好,四川省职工服务网是做什么用?  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  如何在阿里云虚拟服务器快速搭建网站?  Python自动化办公教程_ExcelWordPDF批量处理案例  Linux系统命令中tree命令详解  深圳网站制作的公司有哪些,dido官方网站?  如何在宝塔面板中创建新站点?  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  简历在线制作网站免费版,如何创建个人简历?  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  如何在新浪SAE免费搭建个人博客?  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  长沙企业网站制作哪家好,长沙水业集团官方网站?  车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?  微信小程序 闭包写法详细介绍  UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】  太平洋网站制作公司,网络用语太平洋是什么意思?  Laravel观察者模式如何使用_Laravel Model Observer配置  Python3.6正式版新特性预览  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  零服务器AI建站解决方案:快速部署与云端平台低成本实践  绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信  EditPlus中的正则表达式 实战(1)  如何在建站宝盒中设置产品搜索功能?  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  Laravel怎么实现支付功能_Laravel集成支付宝微信支付  如何实现建站之星域名转发设置?  Laravel如何发送系统通知?(Notification渠道示例)  Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  三星、SK海力士获美批准:可向中国出口芯片制造设备  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  浅谈redis在项目中的应用  微信公众帐号开发教程之图文消息全攻略  Laravel如何使用Blade组件和插槽?(Component代码示例)  Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理  如何做网站制作流程,*游戏网站怎么搭建?  Bootstrap整体框架之CSS12栅格系统  浅谈Javascript中的Label语句  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  晋江文学城电脑版官网 晋江文学城网页版直接进入