Promise 是解决回调嵌套、统一错误处理、控制异步流程的核心机制,而非简单语法糖;应优先使用 fetch、async/await 等已封装 Promise 的接口,仅在包装回调式异步操作(如 setTimeout、事件监听)时才需手写 new Promise()。
Promise 不是用来“学完就用”的语法糖,而是解决回调嵌套、统一错误处理、控制异步流程的核心机制。直接写 new Promise() 多数时候是错的——优先用 fetch()、async/await 或已封装好的返回 Promise 的函数。
new Promise()
只有当你需要把**不支持 Promise 的异步操作**(比如基于回调的 API、定时器、事件监听)包装成 Promise 时,才需要手动构造。
setTimeout、XMLHttpRequest(旧式)、addEventListener(如图片加载完成)fetch().then())里又包一层 new Promise(),导致多余状态和难以调试的 rejected 未捕获setTimeout):function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}.then() 和 .catch() 的链式调用陷阱每个 .then() 返回的是**新的 Promise**,不是原 Promise;一旦中间某个 .then() 抛出错误或返回被 reject 的 Promise,后续的 .then() 就会被跳过,直到遇到 .catch()。
promise.then(fn1).then(fn2).catch(handleError) —— 只能捕获 fn1 和 fn2 内部抛出的错误,无法捕获初始 promise 的 rejectpromise.then(fn1).then(fn2).catch(handleError) 是合理的,但要清楚 handleError 覆盖的是整条链的 reject;若只想捕获某一步,需在对应 .then() 后接 .catch()
.catch() 实际等价于 .then(null, rejectionHandler),别漏掉它前面的逗号逻辑async/await 并不是 Promise 的替代品,而是语法糖asyn 函数内部的 
await 必须用于 Promise(或 thenable),且函数本身**一定返回 Promise**——即使你 return 42,也会被自动包装成 Promise.resolve(42)。
await 会“阻塞线程”,其实只是暂停当前 async 函数执行,JS 主线程依然自由运行其他任务try/catch,不能只靠外部 .catch(),因为 await 后的 reject 会变成 throw
await 串行化:await fetch(a); await fetch(b) 是串行;应写 await Promise.all([fetch(a), fetch(b)])
真正难的不是写对 Promise,而是判断该不该用、在哪一层做 reject、错误是否该继续向上抛。很多 bug 来自把网络错误吞掉却不通知 UI,或在工具函数里 catch 了却没 re-throw,导致上层永远收不到失败信号。