回调是「把函数交给别人,让别人到时候再调用」的编程手法。它驱动着异步操作、定时器和图形界面的事件处理,是理解事件循环与 Listener 模式的核心。
回调(callback):客户端提供给模块的一个函数,供模块在合适的时机调用。
回调让控制流发生「反转」:不是我们主动调用库,而是库在事件发生时调用我们提供的函数。
map、filter。// 同步回调
[1, 2, 3].map(x => x * 2);
// 异步回调:1 秒后运行
setTimeout(() => console.log("hello"), 1000);
setTimeout(callback, ms) 是最简单的异步回调:它把回调放入队列,至少等到指定毫秒后才执行。注意「至少」——如果事件循环正忙,实际等待可能更久。
TypeScript/JavaScript 用事件循环(event loop)和事件队列(event queue)来执行异步回调。主线程不断从队列中取出任务执行;当任务发起异步操作时,它的回调被排入队列,等待下一轮处理。
事件循环:不断从事件队列取出回调并执行的机制,保证了单线程下异步任务的有序调度。
Promise<T>.then(callback) 把一个回调附加到 Promise 上,并在 Promise 完成时调用它,同时返回一个新的 Promise。这是把回调风格与 Promise 风格桥接起来的关键。
fetch("/api/user")
.then(res => res.json()) // 回调 1:解析 JSON
.then(user => user.name) // 回调 2:取出名字
.then(name => console.log(name)); // 回调 3:打印
await 并不是魔法——它的本质是:把 await 之后的剩余计算包装成一个 then 回调,附加到被等待的 Promise 上。理解这一点,就能在回调与 async/await 之间自由切换。
// 这两种写法在语义上等价:
async function f() {
const x = await p;
console.log(x);
}
function f() {
return p.then(x => console.log(x));
}
HTML 元素构成一棵树,称为文档对象模型(Document Object Model, DOM)。JavaScript 可以读取和修改这棵树,从而动态改变页面内容和结构。
GUI 事件处理采用监听者模式(Listener pattern):
const button = document.querySelector("#submit");
button.addEventListener("click", (event) => {
console.log("按钮被点击了");
});
removeEventListener),否则会造成内存泄漏和意外行为。