什么是Promise_如何用它改善异步代码【教程】

6次阅读

promise 是为解决回调地狱而生的异步抽象,不能消除异步但能避免嵌套和错误传递混乱;其构造函数需传入立即执行的executor函数,含resolve/reject参数,缺一不可。

什么是Promise_如何用它改善异步代码【教程】

Promise 不是语法糖,而是为解决回调地狱而生的异步抽象;它不能消除异步,但能让你写异步代码时不再被嵌套和错误传递拖垮。

Promise 构造函数怎么写才不会立即报错

直接 new Promise() 时,构造函数必须接收一个执行器函数(executor),且该函数会立即同步执行。漏掉参数、传错类型、或在 executor 内抛出未捕获异常,都会导致 Uncaught (in promise) Error

  • 正确写法:new Promise((resolve, reject) => { /* 异步操作 */ }),两个参数缺一不可
  • reject 不等于 throw:用 throw new Error() 在 executor 内会自动转为 reject,但不推荐依赖这点——显式调用 reject() 更可控
  • executor 内不能 return 值来“返回结果”,Promise 的值只能由 resolve()reject() 触发

then 和 catch 的链式调用为什么有时不生效

then() 返回的是新 Promise,不是原对象;如果某个 then() 回调里没返回值或返回普通值,后续 then() 会收到 undefined 或该值,但不会中断链。真正中断链的是抛错或返回被 reject 的 Promise。

  • 常见陷阱:then(() => console.log('done')) 后接 catch() —— 这个 then 没抛错、也没返回 Promise,所以 catch 捕不到前面的逻辑错误
  • 想让错误穿透,确保每个 then 要么返回 Promise,要么不吞异常;或者统一用 .catch() 放在链末尾
  • catch() 实际等价于 then(NULL, rejectionHandler),只捕获前一个 Promise 的 rejection,不捕获自身回调里的同步错误(除非你手动 throw

async/await 是 Promise 的替代品吗

不是替代,是语法糖。每个 async 函数都隐式返回 Promise,await 只是暂停执行并解包 Promise 的 fulfilled 值(或抛出 rejection)。它没改变 Promise 的本质行为,只是让书写更线性。

  • await 只能在 async 函数内用,否则报 SyntaxError: await is only valid in async functions
  • await 后面如果不是 Promise,会被自动包装成 Promise.resolve(value),所以 await 42 是合法的
  • 错误处理仍需 try/catch:因为 await 遇到 rejected Promise 会直接 throw,不 catch 就变成未处理拒绝
  • 并发控制要注意:await Promise.all([p1, p2]) 和逐个 await p1; await p2; 性能差别巨大

真正难的不是写对 Promise,而是判断什么时候该用 Promise.allSettled 而不是 Promise.all,或者要不要在 finally 里清理资源——这些细节不会报错,但会让程序在边界条件下静默失败。

text=ZqhQzanResources