JavaScript 是单线程语言,同一时间只能执行一个任务。如果用同步方式发起网络请求,浏览器会「卡住」直到请求完成。异步编程让 JS 可以在等待耗时操作时继续执行其他代码。
function fetchData(url, callback) {
setTimeout(() => {
callback(null, { data: '结果' });
}, 1000);
}
fetchData('/api/user', (err, data) => {
if (err) { console.error('失败:', err); return; }
console.log('成功:', data);
});
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功的结果');
}, 1000);
});
myPromise
.then(result => console.log(result))
.catch(err => console.error(err))
.finally(() => console.log('完成'));
// 并行执行,全部成功才成功
Promise.all([fetch(url1), fetch(url2)])
.then(([res1, res2]) => console.log('全部完成'));
// 并行执行,返回最快的结果
Promise.race([fetch(url1), fetch(url2)])
.then(fastest => console.log('最快完成'));
async function getUser() {
try {
const response = await fetch('/api/user');
const data = await response.json();
console.log(data);
return data;
} catch (error) {
console.error('请求失败:', error);
}
}
// 串行(慢)
const a = await fetch('/api/a');
const b = await fetch('/api/b');
// 并行(快)
const [a, b] = await Promise.all([
fetch('/api/a'),
fetch('/api/b'),
]);
// 防抖:停止操作后才执行
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// 节流:固定间隔只执行一次
function throttle(fn, interval) {
let last = 0;
return function(...args) {
const now = Date.now();
if (now - last >= interval) {
last = now;
fn.apply(this, args);
}
};
}
// 使用
input.addEventListener('input', debounce((e) => {
console.log('搜索:', e.target.value);
}, 300));
本篇从回调函数到 Promise 再到 async/await,梳理了 JS 异步编程的演进。async/await 是当前最佳实践,配合 Promise 静态方法可以优雅处理复杂的异步流程。
下一篇:响应式设计:移动优先与媒体查询