javascript中Promise如何使用_如何避免回调地狱?

11次阅读

promise 是需用 new Promise() 构造的对象,执行器函数中必须显式调用 resolve/reject;.then() 链式返回新 Promise,错误需 .catch() 或 try/catch 捕获;async/await 是语法糖但需在 async 函数内使用;Promise 状态不可逆,未处理 rejection 会静默失败。

javascript中Promise如何使用_如何避免回调地狱?

Promise 基本写法:用 new Promise() 包裹异步操作

Promise 不是语法糖,而是一个对象,必须用 new Promise() 构造,且传入一个执行器函数(executor),它接收 resolvereject 两个参数。常见错误是忘记 return、漏掉 reject、或在同步错误中没调用 reject

正确示例:

const fetchUser = () => {   return new Promise((resolve, reject) => {     setTimeout(() => {       const success = Math.random() > 0.3;       if (success) {         resolve({ id: 123, name: 'Alice' });       } else {         reject(new Error('Network failed'));       }     }, 500);   }); };
  • resolvereject 必须显式调用,不会自动触发
  • 异步操作(如 setTimeoutfetch)必须放在 executor 内部,不能“先执行再包 Promise”
  • 同步抛错(比如 jsON.parse 错误)不会被 Promise 捕获,需手动 try/catch + reject

.then().catch() 链式调用:每个 .then() 返回新 Promise

链式调用的关键在于:每个 .then() 的返回值会成为下一个 .then() 的输入;如果返回的是 Promise,则自动等待其完成;如果抛错或返回 Promise.reject(),后续 .then() 会被跳过,直到遇到 .catch()

避免回调地狱的核心就在这里:把嵌套变成扁平链。

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

fetchUser()   .then(user => fetchPosts(user.id))   .then(posts => filterActive(posts))   .then(filtered => saveToCache(filtered))   .catch(err => console.error('Failed at:', err.message));
  • 不要在 .then() 里写 if/else 分支并混用 returnthrow —— 容易漏掉错误路径
  • .catch() 只捕获前面 Promise 链中的 rejection,不捕获 .then() 内部的同步异常(除非你手动 throw
  • 多个并行请求用 Promise.all([p1, p2, p3]),别串行调用三次 .then()

async/await 是 Promise 的语法糖:但 await 必须在 async 函数内

很多人写 await fetchUser() 却忘了外层函数加 async,结果报错 Uncaught SyntaxError: await is only valid in async function

正确写法:

const loadProfile = async () => {   try {     const user = await fetchUser();     const posts = await fetchPosts(user.id);     return { user, posts };   } catch (err) {     console.error('Load failed:', err);     throw err; // 不要静默吞掉错误,下游可能依赖这个 rejection   } };
  • await 后面必须是 Promise(或 thenable),否则直接返回原值
  • try/catch 捕获的是 Promise rejection,不是所有 JS 异常(比如 undefined.foo() 还是同步报错)
  • 循环中慎用 awaitfor-of + await 是串行,想并行得用 Promise.all(…map(async …))

容易被忽略的坑:Promise 状态不可逆、未处理的 rejection 会静默失败

Promise 一旦 resolvereject,状态就锁定,再次调用另一个方法无效。更危险的是:未被 .catch()try/catch 捕获的 rejection,在现代浏览器node.js 中会触发 unhandledrejection 事件,但默认不报错 —— 你的请求失败了,控制台却没提示。

  • 全局监听未处理 rejection(开发期必备):
    window.addEventListener('unhandledrejection', e => console.error(e.reason));
  • 避免“忘记 return”:箭头函数单表达式隐式 return,但若写成块级结构 () => { doSomething(); } 就不返回 Promise,导致链中断
  • 构造 Promise 时,reject 最好传 Error 实例,而不是字符串 —— 方便追踪和统一错误处理

text=ZqhQzanResources