javascript Promise是什么_如何使用then和catch

11次阅读

promise封装异步操作的状态容器,有 pending、fulfilled、rejected 三种不可逆状态;then 注册响应处理器并返回新 Promise,catch 应置于链尾统一捕获所有错误;构造函数执行器同步运行。

javascript Promise是什么_如何使用then和catch

Promise 是什么:它不是回调函数的语法糖,而是异步操作的状态容器

Promise 本质是一个对象,用来封装一个**尚未完成但终将完成(或失败)的异步操作**。它有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)。状态一旦改变(fulfilledrejected),就不可逆,也不会再变。

和直接写 setTimeoutXMLHttpRequest 回调不同,Promise 把“操作”和“响应”解耦了——你创建 Promise 时就定义好它“做什么”,之后用 thencatch 去声明“成功后怎么做”“失败后怎么做”,而不是把逻辑嵌在回调里。

如何正确使用 then:它接收两个可选函数,但只处理上一个 Promise 的结果

then 不是“等异步结束就执行”,而是“注册对前一个 Promise 状态的响应处理器”。它的第一个参数处理 fulfilled,第二个参数处理 rejected(但不推荐在这里捕获错误)。

  • then 总是返回一个新的 Promise,所以可以链式调用;返回值会自动包装成 resolved Promise,抛出异常则变成 rejected
  • 如果只想处理成功,第二个参数留空或传 undefined,别写 NULL(会报错)
  • 不要在 then 的第二个参数里做复杂错误处理——它无法捕获第一个参数内部抛出的错误(比如 throw new Error()),这部分会被忽略,导致静默失败
fetch('/api/user')   .then(response => {     if (!response.ok) throw new Error('HTTP error');     return response.json();   })   .then(data => console.log(data))   .catch(err => console.error('出错了:', err)); // 所有 reject 和上面 throw 都会进这里

为什么 catch 必须放在链尾,而不是每个 then 后面都加

catchthen(undefined, rejectionHandler) 的语法糖,但它能捕获链中**任何上游 Promise 的 rejection**,包括 then 回调里抛出的错误。如果在每个 then 后都跟 catch,不仅冗余,还会中断链式流程——一旦某个 catch 处理完错误并没重新抛出,后续 then 仍会执行(因为 catch 返回的是 fulfilled Promise)。

立即学习Java免费学习笔记(深入)”;

  • 常见错误:写成 .then(...).catch(...).then(...),以为第二个 then 只在成功时运行,其实它也会收到前一个 catch 的返回值
  • 正确做法:单个 catch 放在链最末,覆盖整条链的异常流
  • 极少数需要局部容错时,可在某步 then 内部用 try/catch,或返回 Promise.resolve().catch(...) 转换错误为值

容易被忽略的关键点:Promise 构造函数里的执行器是同步运行的

很多人误以为 new Promise(() => {...}) 里的函数是“异步执行”的,其实它**立即同步执行**。里面的 resolvereject 调用也同步发生,只是 Promise 的 then / catch 回调会被推入微任务队列,等当前同步代码跑完才执行。

  • 这意味着:构造函数里写 console.log('start'),然后 resolve(1),再 console.log('end'),输出顺序是 start → end → then 回调
  • 如果你忘了调用 resolvereject,Promise 会永远卡在 pending,既不走 then 也不走 catch,且无任何提示
  • 浏览器开发者工具里看 Promise 状态,pending 不代表“正在异步执行”,只代表“还没被决议”

text=ZqhQzanResources