异步编程的几种方式
1. 回调函数(Callback)
就是最基础的“你做完一件事后,告诉我一声,我继续做下一步”。比如:
setTimeout(() => {
console.log("时间到!");
}, 1000);但如果你一个回调里再套一个回调,再套一个……代码就会变成“金字塔”,很难看,这就是传说中的“回调地狱”。
2. Promise
Promise 就像“承诺”:你给我一个任务,我答应你做完之后告诉你结果。你可以用 .then() 来处理成功,.catch() 来处理失败。比如:
fetch('/api/data')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error("出错了", err));比回调清爽多了,不用层层嵌套。
3. Async/Await
这是 Promise 的“语法糖”,让异步代码看起来像同步代码,特别直观。比如:
async function getData() {
try {
const res = await fetch('/api/data');
const data = await res.json();
console.log(data);
} catch (err) {
console.error("出错了", err);
}
}用 await 等待异步操作完成,代码写起来就像“一步一步来”,非常清晰。
4. 事件监听(Event Listeners)
比如你在网页上点一个按钮,浏览器“监听”到这个事件,然后执行你绑定的函数。适合处理用户交互或自定义事件。
5. 生成器(Generators)
这个用得少,简单说就是可以“暂停”和“继续”执行的函数,适合做一些复杂的流程控制。
6. 观察者模式(Observables)
比如 RxJS 里的 Observable,用来处理“事件流”,比如连续的鼠标点击、定时任务等。适合复杂的前端交互场景。
怎么避免回调地狱?
1. 用 Promise 链式调用
别再嵌套回调了,用 .then() 一路链下去,清爽!
doSomething()
.then(result1 => doSomethingElse(result1))
.then(result2 => doThirdThing(result2))
.catch(err => console.error(err));2. 用 async/await
这是目前最推荐的方式,代码写起来像讲故事一样顺。
async function main() {
try {
const result1 = await doSomething();
const result2 = await doSomethingElse(result1);
const result3 = await doThirdThing(result2);
console.log(result3);
} catch (err) {
console.error("出错了", err);
}
}3. 拆分函数,别写一坨
把复杂的逻辑拆成小函数,每个函数只干一件事,这样代码既清晰又好维护。
4. 用 Promise.all() 并行处理
如果几个异步操作互不依赖,可以同时做,等全部完成再继续。
Promise.all([fetchData1(), fetchData2(), fetchData3()])
.then(results => console.log(results));5. 用控制流库(比如 Async.js)
如果你还在用回调,又不想用 Promise,可以用 Async.js 这样的库,帮你把流程理清楚。
总结一句话
别再写层层嵌套的回调了!用 Promise,更推荐用 async/await,代码清爽又好懂!