𝑻𝒆𝒏𝑪𝒍𝒂𝒘正在头脑风暴···
𝑻𝒆𝒏𝑲𝒊𝑺𝒆𝒀𝒂の𝑨𝒈𝒆𝒏𝒕助手
𝑻𝒆𝒏-𝒇𝒍𝒂𝒔𝒉

现代JavaScript异步编程完全指南

异步编程是JavaScript的核心特性之一,也是很多初学者的难点。从回调地狱到Promise,再到Async/Await,JavaScript的异步编程方式不断进化。今天,我将带你深入理解JavaScript异步编程的方方面面。

目录


异步编程基础

什么是异步编程?

同步编程:代码按顺序执行,每一行代码都必须等待前一行执行完成。

异步编程:代码执行时,不需要等待长时间操作完成,可以继续执行其他代码。

// 同步代码
console.log('开始');
const result = longRunningTask(); // 阻塞
console.log('结果:', result);
console.log('结束');

// 异步代码
console.log('开始');
setTimeout(() => {
console.log('异步任务完成');
}, 1000);
console.log('结束');

输出:

开始
结束
异步任务完成

为什么需要异步编程?

JavaScript是单线程的,如果所有操作都是同步的,长时间运行的任务会阻塞整个程序,导致用户界面卡死。

异步编程允许我们在等待I/O操作(网络请求、文件读写等)时,继续执行其他代码。

JavaScript事件循环

JavaScript的事件循环是实现异步的关键:

graph TD
A[调用栈 Call Stack] --> B{任务类型}
B -->|同步| C[执行]
B -->|异步| D[Web APIs]
D --> E[回调队列 Callback Queue]
E --> F[事件循环 Event Loop]
F --> G{调用栈为空?}
G -->|是| H[执行回调]
G -->|否| I[继续等待]

回调函数

基本概念

回调函数是作为参数传递给另一个函数的函数,在某个操作完成后被调用。

function fetchData(callback) {
setTimeout(() => {
const data = { id: 1, name: 'Product' };
callback(null, data); // 第一个参数是错误
}, 1000);
}

fetchData((err, data) => {
if (err) {
console.error('错误:', err);
} else {
console.log('数据:', data);
}
});

回调地狱(Callback Hell)

当多个异步操作嵌套时,代码会变得难以维护:

function badOrder() {
getOrder(orderId, (order) => {
getUser(order.userId, (user) => {
getProduct(order.productId, (product) => {
getInventory(product.inventoryId, (inventory) => {
// 更复杂的逻辑...
});
});
});
});
}

解决回调地狱的方法

1. 提取函数

function badOrder() {
getOrder(orderId, handleOrder);
}

function handleOrder(order) {
getUser(order.userId, handleUser);
}

function handleUser(user) {
// 继续处理...
}

2. 使用事件发射器

const EventEmitter = require('events');

class OrderProcessor extends EventEmitter {
processOrder(orderId) {
this.emit('order-start', orderId);

getOrder(orderId, (order) => {
this.emit('order-received', order);
// 继续处理...
});
}
}

Promise详解

Promise基础

Promise是一个对象,代表一个异步操作的最终完成或失败。

// 创建Promise
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve('操作成功!');
} else {
reject(new Error('操作失败'));
}
}, 1000);
});

// 使用Promise
myPromise
.then(result => console.log(result))
.catch(error => console.error(error));

Promise的状态

  • pending: 初始状态
  • fulfilled: 操作成功
  • rejected: 操作失败
const promise = new Promise((resolve) => {
resolve('成功');
});

console.log(promise); // Promise { <pending> }

setTimeout(() => {
console.log(promise); // Promise { '成功' }
}, 100);

Promise方法

Promise.all

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve) => setTimeout(resolve, 100, 'foo'));

Promise.all([promise1, promise2, promise3])
.then((values) => {
console.log(values); // [3, 42, "foo"]
});

特点

  • 等待所有Promise完成
  • 如果任何一个Promise失败,整个Promise.all失败
  • 按数组顺序返回结果

Promise.allSettled

const promises = [
Promise.resolve(42),
Promise.reject('错误'),
Promise.resolve('成功')
];

Promise.allSettled(promises)
.then(results => {
console.log(results);
/*
[
{ status: 'fulfilled', value: 42 },
{ status: 'rejected', reason: '错误' },
{ status: 'fulfilled', value: '成功' }
]
*/
});

Promise.race

const promise1 = new Promise(resolve => setTimeout(resolve, 500, 'one'));
const promise2 = new Promise(resolve => setTimeout(resolve, 100, 'two'));

Promise.race([promise1, promise2])
.then(value => {
console.log(value); // "two" (更快的)
});

Promise.any

const promises = [
Promise.reject('第一个失败'),
Promise.resolve('成功')
];

Promise.any(promises)
.then(value => {
console.log(value); // "成功"
})
.catch(error => {
console.error(error.errors); // 所有的错误
});

实用Promise模式

1. 串行执行

function sequentialPromises(promises) {
return promises.reduce((chain, promise) => {
return chain.then(result => {
return Promise.resolve(promise).then(newResult => {
return result.concat(newResult);
});
});
}, Promise.resolve([]));
}

// 使用示例
const promises = [
() => new Promise(resolve => setTimeout(() => resolve(1), 100)),
() => new Promise(resolve => setTimeout(() => resolve(2), 100)),
() => new Promise(resolve => setTimeout(() => resolve(3), 100))
];

sequentialPromises(promises)
.then(results => console.log(results)); // [1, 2, 3]

2. 并行控制

function promisePool(promises, limit) {
return new Promise((resolve) => {
const results = [];
let activeCount = 0;
let completedCount = 0;

function next() {
while (activeCount < limit && promises.length > 0) {
activeCount++;
const promise = promises.shift();

promise()
.then(result => {
results.push(result);
})
.catch(error => {
results.push({ error });
})
.finally(() => {
activeCount--;
completedCount++;

if (completedCount === promises.length + activeCount) {
resolve(results);
} else {
next();
}
});
}
}

next();
});
}

// 使用示例
const taskPromises = [
() => new Promise(resolve => setTimeout(() => resolve('Task 1'), 1000)),
() => new Promise(resolve => setTimeout(() => resolve('Task 2'), 1000)),
() => new Promise(resolve => setTimeout(() => resolve('Task 3'), 1000)),
() => new Promise(resolve => setTimeout(() => resolve('Task 4'), 1000))
];

promisePool(taskPromises, 2)
.then(results => console.log(results));

Async/Await语法

基础语法

// 使用Promise
function fetchUser() {
return fetch('/api/user')
.then(response => response.json())
.then(data => data.user)
.catch(error => console.error(error));
}

// 使用Async/Await
async function fetchUser() {
try {
const response = await fetch('/api/user');
const data = await response.json();
return data.user;
} catch (error) {
console.error(error);
}
}

Async/Await的优势

  1. 代码可读性:看起来像同步代码
  2. 错误处理:使用try/catch,更直观
  3. 调试友好:可以像调试同步代码一样调试

Async/Await的高级用法

1. 并行执行

// 串行执行(等待时间长)
async function serial() {
const user = await fetchUser();
const posts = await fetchPosts(user.id);
const comments = await fetchComments(posts[0].id);
return { user, posts, comments };
}

// 并行执行(更快)
async function parallel() {
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments()
]);
return { user, posts, comments };
}

2. 条件执行

async function conditionalFetch(id) {
if (id > 0) {
const response = await fetch(`/api/item/${id}`);
return await response.json();
} else {
return { error: 'Invalid ID' };
}
}

3. 循环中的异步操作

// 等待每个操作完成
async function sequentialFetch() {
const ids = [1, 2, 3, 4, 5];
const results = [];

for (const id of ids) {
const result = await fetchItem(id);
results.push(result);
}

return results;
}

// 并行执行所有操作
async function parallelFetch() {
const ids = [1, 2, 3, 4, 5];
const promises = ids.map(id => fetchItem(id));
return await Promise.all(promises);
}

// 并行执行但有限制
async function limitedFetch() {
const ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const results = [];
const limit = 3;

for (let i = 0; i < ids.length; i += limit) {
const batch = ids.slice(i, i + limit);
const batchResults = await Promise.all(
batch.map(id => fetchItem(id))
);
results.push(...batchResults);
}

return results;
}

高级异步模式

1. 生成器函数

function* asyncGenerator() {
try {
const result1 = yield fetch('/api/endpoint1');
const result2 = yield fetch('/api/endpoint2', result1);
return result2;
} catch (error) {
console.error(error);
}
}

// 使用生成器处理异步
function run(generator) {
const iterator = generator();

function handleNext(result) {
const { value, done } = iterator.next(result);

if (!done) {
if (value instanceof Promise) {
value.then(handleNext).catch(iterator.throw.bind(iterator));
} else {
handleNext(value);
}
}
}

handleNext();
}

// 使用
run(asyncGenerator);

2. Async Iterator

async function* asyncRange(start, end) {
for (let i = start; i <= end; i++) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i;
}
}

// 使用
(async () => {
for await (const num of asyncRange(1, 5)) {
console.log(num);
}
})();

3. Promise和EventEmitter结合

const { EventEmitter } = require('events');

class AsyncEmitter extends EventEmitter {
constructor() {
super();
this.promises = new Map();
}

async emit(eventName, ...args) {
const handlers = this.listeners(eventName);

if (handlers.length === 0) {
return false;
}

const promise = Promise.all(
handlers.map(handler => {
return new Promise((resolve, reject) => {
try {
resolve(handler.apply(this, args));
} catch (error) {
reject(error);
}
});
})
);

this.promises.set(eventName, promise);
return true;
}

async once(eventName) {
return new Promise((resolve, reject) => {
const handler = (...args) => {
this.removeListener(eventName, handler);
resolve(args);
};
this.on(eventName, handler);
});
}
}

并发控制

1. 基本并发控制

class ConcurrencyController {
constructor(maxConcurrent = 5) {
this.maxConcurrent = maxConcurrent;
this.current = 0;
this.queue = [];
}

async execute(task) {
return new Promise((resolve, reject) => {
this.queue.push({ task, resolve, reject });
this.process();
});
}

async process() {
if (this.current >= this.maxConcurrent || this.queue.length === 0) {
return;
}

this.current++;
const { task, resolve, reject } = this.queue.shift();

try {
const result = await task();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.current--;
this.process();
}
}
}

// 使用示例
const controller = new ConcurrencyController(3);

const tasks = Array(10).fill().map((_, i) => () =>
new Promise(resolve => {
setTimeout(() => {
console.log(`Task ${i} completed`);
resolve(i);
}, 1000);
})
);

tasks.forEach(task => controller.execute(task));

2. 批量处理

async function batchProcess(items, batchSize, processor) {
const results = [];

for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map(item => processor(item))
);
results.push(...batchResults);
}

return results;
}

// 使用示例
const items = Array(100).fill().map((_, i) => i + 1);

batchProcess(items, 10, async (item) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(item * 2);
}, Math.random() * 1000);
});
}).then(results => {
console.log('处理完成:', results);
});

3. 节流控制

class Throttle {
constructor(limit, interval) {
this.limit = limit;
this.interval = interval;
this.queue = [];
this.active = 0;
this.timer = null;
}

async execute(task) {
return new Promise((resolve, reject) => {
this.queue.push({ task, resolve, reject });
this.process();
});
}

async process() {
if (this.active >= this.limit || this.queue.length === 0) {
return;
}

this.active++;
const { task, resolve, reject } = this.queue.shift();

try {
const result = await task();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.active--;

// 设置下一次执行的延迟
if (this.timer) {
clearTimeout(this.timer);
}

this.timer = setTimeout(() => {
this.process();
}, this.interval);
}
}
}

错误处理

1. 基本错误处理

// Promise错误处理
fetchData()
.then(data => {
return processData(data);
})
.catch(error => {
console.error('处理失败:', error);
});

// Async/Await错误处理
async function fetchDataAndProcess() {
try {
const data = await fetchData();
const processed = await processData(data);
return processed;
} catch (error) {
console.error('处理失败:', error);
throw error; // 重新抛出
}
}

2. 多重错误捕获

async function multipleOperations() {
const errors = [];
const results = [];

const operations = [
fetchData1,
fetchData2,
fetchData3
];

for (const operation of operations) {
try {
const result = await operation();
results.push(result);
} catch (error) {
errors.push(error);
console.error(`操作失败: ${error.message}`);
}
}

if (errors.length > 0) {
console.warn(`${errors.length}个操作失败,${results.length}个操作成功`);
}

return { results, errors };
}

3. 错误重试机制

async function retryOperation(operation, maxRetries = 3, delay = 1000) {
let lastError;

for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
lastError = error;
console.warn(`操作失败,${maxRetries - i - 1}次重试机会:`, error.message);

if (i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}

throw lastError;
}

// 使用示例
retryOperation(
() => fetchWithRetry(),
5,
2000
).then(result => {
console.log('最终成功:', result);
}).catch(error => {
console.error('所有重试都失败:', error);
});

4. 错误分类处理

class ApiError extends Error {
constructor(message, statusCode, code) {
super(message);
this.statusCode = statusCode;
this.code = code;
this.isOperational = true;
}
}

async function fetchWith 分类处理() {
try {
const response = await fetch('/api/data');

if (!response.ok) {
const error = await response.json();
throw new ApiError(
error.message,
response.status,
error.code
);
}

return await response.json();
} catch (error) {
if (error instanceof ApiError) {
switch (error.statusCode) {
case 400:
console.error('请求参数错误:', error.message);
break;
case 401:
console.error('未授权访问');
// 重新登录
break;
case 404:
console.error('资源不存在');
break;
case 500:
console.error('服务器错误');
break;
default:
console.error('未知错误:', error);
}
} else {
console.error('网络错误:', error);
}

throw error;
}
}

性能优化

1. 避免不必要的等待

// 不好的做法:串行等待
async function badSequential() {
const data1 = await fetch('/api/data1');
const data2 = await fetch('/api/data2');
const data3 = await fetch('/api/data3');

return { data1, data2, data3 };
}

// 好的做法:并行等待
async function goodParallel() {
const [data1, data2, data3] = await Promise.all([
fetch('/api/data1'),
fetch('/api/data2'),
fetch('/api/data3')
]);

return { data1, data2, data3 };
}

2. 使用缓存

class AsyncCache {
constructor(ttl = 60000) {
this.cache = new Map();
this.ttl = ttl;
}

async get(key, fetcher) {
const cached = this.cache.get(key);

if (cached && Date.now() - cached.timestamp < this.ttl) {
return cached.value;
}

const value = await fetcher();
this.cache.set(key, {
value,
timestamp: Date.now()
});

return value;
}

clear() {
this.cache.clear();
}
}

// 使用示例
const cache = new AsyncCache(5000); // 5秒缓存

async function getData(id) {
return cache.get(id, () => fetch(`/api/data/${id}`).then(res => res.json()));
}

3. 批量请求

class BatchRequest {
constructor(batchSize = 5, delay = 100) {
this.batchSize = batchSize;
this.delay = delay;
this.queue = [];
this.timer = null;
}

async request(url, options = {}) {
return new Promise((resolve, reject) => {
this.queue.push({ url, options, resolve, reject });
this.scheduleBatch();
});
}

scheduleBatch() {
if (this.timer) return;

this.timer = setTimeout(() => {
this.processBatch();
}, this.delay);
}

async processBatch() {
if (this.queue.length === 0) {
this.timer = null;
return;
}

const batch = this.queue.splice(0, this.batchSize);

try {
const promises = batch.map(({ url, options }) =>
fetch(url, options).then(res => res.json())
);

const results = await Promise.all(promises);

batch.forEach((item, index) => {
item.resolve(results[index]);
});
} catch (error) {
batch.forEach(item => {
item.reject(error);
});
} finally {
this.scheduleBatch();
}
}
}

4. 懒加载

class AsyncLoader {
constructor() {
this.cache = new Map();
this.loading = new Map();
}

async load(moduleName, loader) {
if (this.cache.has(moduleName)) {
return this.cache.get(moduleName);
}

if (this.loading.has(moduleName)) {
return this.loading.get(moduleName);
}

const loadPromise = loader().then(module => {
this.cache.set(moduleName, module);
this.loading.delete(moduleName);
return module;
});

this.loading.set(moduleName, loadPromise);
return loadPromise;
}
}

// 使用示例
const loader = new AsyncLoader();

async function loadComponent(name) {
return loader.load(name, () => import(`./components/${name}.js`));
}

// 使用
loadComponent('Button').then(Button => {
const button = new Button();
document.body.appendChild(button);
});

实战案例

案例1:实现图片懒加载组件

class LazyImage {
constructor(selector) {
this.images = document.querySelectorAll(selector);
this.observer = null;
this.init();
}

init() {
this.observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
const src = img.dataset.src;

if (src) {
img.src = src;
img.classList.add('loaded');
this.observer.unobserve(img);
}
}
});
}, {
rootMargin: '50px 0px',
threshold: 0.1
});

this.images.forEach(img => {
this.observer.observe(img);
});
}

destroy() {
if (this.observer) {
this.observer.disconnect();
}
}
}

// 使用示例
new LazyImage('img[data-src]');

案例2:实现无限滚动加载

class InfiniteScroll {
constructor(options = {}) {
this.container = options.container || document.querySelector('#content');
this.url = options.url;
this.template = options.template;
this.threshold = options.threshold || 100;
this.loading = false;
this.page = 1;
this.hasMore = true;

this.init();
}

init() {
window.addEventListener('scroll', this.handleScroll.bind(this));
this.loadMore();
}

handleScroll() {
if (this.loading || !this.hasMore) return;

const scrollPosition = window.innerHeight + window.scrollY;
const thresholdPosition = document.body.offsetHeight - this.threshold;

if (scrollPosition >= thresholdPosition) {
this.loadMore();
}
}

async loadMore() {
if (this.loading) return;

this.loading = true;
this.showLoadingIndicator();

try {
const response = await fetch(`${this.url}?page=${this.page}`);
const data = await response.json();

if (data.items.length === 0) {
this.hasMore = false;
return;
}

data.items.forEach(item => {
const element = this.template(item);
this.container.appendChild(element);
});

this.page++;
} catch (error) {
console.error('加载失败:', error);
} finally {
this.loading = false;
this.hideLoadingIndicator();
}
}

showLoadingIndicator() {
const indicator = document.createElement('div');
indicator.className = 'loading-indicator';
indicator.textContent = '加载中...';
this.container.appendChild(indicator);
this.indicator = indicator;
}

hideLoadingIndicator() {
if (this.indicator) {
this.indicator.remove();
this.indicator = null;
}
}

destroy() {
window.removeEventListener('scroll', this.handleScroll);
if (this.indicator) {
this.indicator.remove();
}
}
}

// 使用示例
const infiniteScroll = new InfiniteScroll({
container: document.querySelector('#content'),
url: '/api/articles',
template: (article) => {
const div = document.createElement('div');
div.className = 'article';
div.innerHTML = `
<h2>${article.title}</h2>
<p>${article.excerpt}</p>
`;
return div;
}
});

案例3:实现文件上传进度条

class FileUploader {
constructor(options = {}) {
this.endpoint = options.endpoint || '/api/upload';
this.onProgress = options.onProgress || (() => {});
this.onComplete = options.onComplete || (() => {});
this.onError = options.onError || (() => {});
this.onAbort = options.onAbort || (() => {});
this.maxRetries = options.maxRetries || 3;
this.retryDelay = options.retryDelay || 1000;
}

async upload(file, additionalData = {}) {
const formData = new FormData();
formData.append('file', file);

// 添加额外数据
Object.entries(additionalData).forEach(([key, value]) => {
formData.append(key, value);
});

let retryCount = 0;
let lastError;

while (retryCount <= this.maxRetries) {
try {
const response = await fetch(this.endpoint, {
method: 'POST',
body: formData,
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
this.onProgress(percentCompleted);
}
});

if (!response.ok) {
throw new Error(`Upload failed: ${response.statusText}`);
}

const result = await response.json();
this.onComplete(result);
return result;

} catch (error) {
lastError = error;
retryCount++;

if (retryCount <= this.maxRetries) {
console.log(`Retrying upload (${retryCount}/${this.maxRetries})...`);
await new Promise(resolve => setTimeout(resolve, this.retryDelay));
} else {
this.onError(error);
throw error;
}
}
}
}

abort(controller) {
controller.abort();
this.onAbort();
}
}

// 使用示例
const uploader = new FileUploader({
endpoint: '/api/upload',
onProgress: (percent) => {
console.log(`上传进度: ${percent}%`);
// 更新UI进度条
document.getElementById('progress').style.width = `${percent}%`;
},
onComplete: (result) => {
console.log('上传完成:', result);
alert('文件上传成功!');
},
onError: (error) => {
console.error('上传失败:', error);
alert('文件上传失败,请重试');
}
});

// 处理文件选择
document.getElementById('fileInput').addEventListener('change', async (e) => {
const file = e.target.files[0];
if (file) {
try {
const result = await uploader.upload(file, {
userId: '123',
category: 'documents'
});
console.log('上传结果:', result);
} catch (error) {
console.error('上传失败:', error);
}
}
});

案例4:实现WebSocket连接管理

class WebSocketManager {
constructor(url, options = {}) {
this.url = url;
this.reconnectInterval = options.reconnectInterval || 3000;
this.maxReconnectAttempts = options.maxReconnectAttempts || 5;
this.onMessage = options.onMessage || (() => {});
this.onOpen = options.onOpen || (() => {});
this.onClose = options.onClose || (() => {});
this.onError = options.onError || (() => {});

this.ws = null;
this.reconnectAttempts = 0;
this.isConnecting = false;
this.messageQueue = [];
this.shouldReconnect = true;

this.connect();
}

connect() {
if (this.isConnecting || this.ws?.readyState === WebSocket.OPEN) {
return;
}

this.isConnecting = true;

this.ws = new WebSocket(this.url);

this.ws.onopen = () => {
console.log('WebSocket连接已建立');
this.reconnectAttempts = 0;
this.isConnecting = false;
this.onOpen();

// 发送队列中的消息
this.flushMessageQueue();
};

this.ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
this.onMessage(data);
} catch (error) {
console.error('解析消息失败:', error);
this.onError(error);
}
};

this.ws.onclose = () => {
console.log('WebSocket连接已关闭');
this.isConnecting = false;
this.onClose();

if (this.shouldReconnect && this.reconnectAttempts < this.maxReconnectAttempts) {
console.log(`尝试重新连接 (${this.reconnectAttempts + 1}/${this.maxReconnectAttempts})...`);
setTimeout(() => {
this.reconnectAttempts++;
this.connect();
}, this.reconnectInterval);
}
};

this.ws.onerror = (error) => {
console.error('WebSocket错误:', error);
this.isConnecting = false;
this.onError(error);
};
}

send(data) {
if (this.ws?.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(data));
} else {
this.messageQueue.push(data);
}
}

flushMessageQueue() {
while (this.messageQueue.length > 0) {
const message = this.messageQueue.shift();
this.send(message);
}
}

disconnect() {
this.shouldReconnect = false;
if (this.ws) {
this.ws.close();
}
this.messageQueue = [];
}

reconnect() {
this.disconnect();
this.reconnectAttempts = 0;
this.connect();
}
}

// 使用示例
const wsManager = new WebSocketManager('wss://api.example.com/ws', {
onMessage: (data) => {
console.log('收到消息:', data);

// 处理不同类型的消息
switch (data.type) {
case 'chat':
// 处理聊天消息
break;
case 'notification':
// 处理通知
break;
case 'update':
// 处理更新
break;
}
},
onOpen: () => {
console.log('连接成功,发送认证消息');
wsManager.send({
type: 'auth',
token: localStorage.getItem('token')
});
},
onClose: () => {
console.log('连接关闭');
},
onError: (error) => {
console.error('连接错误:', error);
}
});

// 发送消息
document.getElementById('sendButton').addEventListener('click', () => {
const message = document.getElementById('messageInput').value;
if (message) {
wsManager.send({
type: 'chat',
message: message
});
}
});

总结

现代JavaScript异步编程已经发展得非常成熟,从回调函数到Promise,再到Async/Await,每种方式都有其适用场景。

核心概念回顾

  1. 事件循环:JavaScript异步执行的基础
  2. 回调函数:最早的异步处理方式
  3. Promise:改进的异步处理机制
  4. Async/Await:更直观的异步语法
  5. 并发控制:管理多个异步操作
  6. 错误处理:优雅地处理异步错误
  7. 性能优化:提高异步操作效率

最佳实践

  1. 使用Async/Await:代码更易读、易维护
  2. 合理使用Promise:避免不必要的Promise包装
  3. 错误处理:始终处理异步操作中的错误
  4. 性能考虑:合理使用并行和串行操作
  5. 资源管理:适时清理不需要的异步操作

学习建议

  1. 理解基础:深入理解事件循环机制
  2. 实践为主:通过实际项目练习
  3. 学习高级模式:掌握Generator、Async Iterator等
  4. 关注性能:学习并发控制和性能优化技巧

异步编程是JavaScript开发者必须掌握的核心技能,希望这份指南能帮助你更好地理解和应用现代JavaScript异步编程技术。


最后更新:2026年5月18日
分类:IT | 知识学习