Promise在javascript中如何运用【教程】

10次阅读

promise 是解决回调嵌套、统一错误处理、控制异步流程的核心机制,而非简单语法糖;应优先使用 fetch、async/await 等已封装 Promise 的接口,仅在包装回调式异步操作(如 setTimeout、事件监听)时才需手写 new Promise()。

Promise在javascript中如何运用【教程】

Promise 不是用来“学完就用”的语法糖,而是解决回调嵌套、统一错误处理、控制异步流程的核心机制。直接写 new Promise() 多数时候是错的——优先用 fetch()async/await 或已封装好的返回 Promise 的函数。

什么时候必须手写 new Promise()

只有当你需要把**不支持 Promise 的异步操作**(比如基于回调的 API、定时器、事件监听)包装成 Promise 时,才需要手动构造。

  • 例如:setTimeoutXMLHttpRequest(旧式)、addEventListener(如图片加载完成)
  • 常见错误:在已有 Promise 的场景(如 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) —— 只能捕获 fn1fn2 内部抛出的错误,无法捕获初始 promise 的 reject
  • 推荐写法:promise.then(fn1).then(fn2).catch(handleError) 是合理的,但要清楚 handleError 覆盖的是整条链的 reject;若只想捕获某一步,需在对应 .then() 后接 .catch()
  • 注意:.catch() 实际等价于 .then(NULL, rejectionHandler),别漏掉它前面的逗号逻辑

async/await 并不是 Promise 的替代品,而是语法糖

async 函数内部的 await 必须用于 Promise(或 thenable),且函数本身**一定返回 Promise**——即使你 return 42,也会被自动包装成 Promise.resolve(42)

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

  • 常见误区:以为 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,导致上层永远收不到失败信号。

text=ZqhQzanResources