跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

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

Promise 是需用 new Promise() 构造的对象,执行器函数中必须显式调用 resolve/reject;.then() 链式返回新 Promise,错误需 .catch() 或 try/catch 捕获;async/await 是语法糖但需在 async 函数内使用;Promise 状态不可逆,未处理 rejection 会静默失败。 Promise 基本写法:用
new Promise()
包裹异步操作 Promise 不是语法糖,而是一个对象,必须用
new Promise()
构造,且传入一个执行器函数(executor),它接收
resolve
和
reject
两个参数。常见错误是忘记
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); }); };
resolve
和
reject
必须显式调用,不会自动触发 异步操作(如
setTimeout
、
fetch
)必须放在 executor 内部,不能“先执行再包 Promise” 同步抛错(比如 JSON.parse 错误)不会被 Promise 捕获,需手动
try/catch
+
reject
.then()
和
.catch()
链式调用:每个
.then()
返回新 Promise 链式调用的关键在于:每个
.then()
的返回值会成为下一个
.then()
的输入;如果返回的是 Promise,则自动等待其完成;如果抛错或返回
Promise.reject()
,后续
.then()
会被跳过,直到遇到
.catch()
。 避免回调地狱的核心就在这里:把嵌套变成扁平链。 立即学习 “ Java免费学习笔记(深入) ”; Comet AI 浏览器 下载 Comet AI 浏览器,体验由 Perplexity AI 驱动的革命性上网方式。内置 AI 助手可实时总结网页、跨标签页对比信息、自动执行任务。告别繁琐操作,让 AI 成为你的浏览副驾,大幅提升研究与工作效率。支持 Windows、macOS、Android 和 iOS。 下载
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
分支并混用
return
和
throw
—— 容易漏掉错误路径
.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()
还是同步报错) 循环中慎用
await
:for-of + await 是串行,想并行得用
Promise.all(…map(async …))
容易被忽略的坑:Promise 状态不可逆、未处理的 rejection 会静默失败 Promise 一旦
resolve
或
reject
,状态就锁定,再次调用另一个方法无效。更危险的是:未被
.catch()
或
try/catch
捕获的 rejection,在现代 浏览器 和 Node. js 中会触发
unhandledrejection
事件,但默认不报错 —— 你的请求失败了,控制台却没提示。 全局监听未处理 rejection(开发期必备):
window.addEventListener('unhandledrejection', e => console.error(e.reason));
避免“忘记 return”:箭头函数单表达式隐式 return,但若写成块级结构
() => { doSomething(); }
就不返回 Promise,导致链中断 构造 Promise 时,
reject
最好传
Error
实例,而不是字符串 —— 方便堆栈追踪和统一错误处理

相关文章