跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
JavaScript异步基础
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= JavaScript异步基础 = '''JavaScript异步编程'''是JavaScript中处理耗时操作(如网络请求、文件读写等)的核心机制,它允许程序在等待这些操作完成时继续执行其他任务,避免阻塞主线程。本章将详细介绍异步编程的基本概念、工作原理及实现方式。 == 同步 vs 异步 == 在'''同步编程'''中,代码按顺序逐行执行,每一行必须等待前一行完成后才能运行。例如: <syntaxhighlight lang="javascript"> console.log("第一步"); console.log("第二步"); // 必须等待第一步完成 console.log("第三步"); // 必须等待第二步完成 </syntaxhighlight> '''异步编程'''则允许某些操作在后台执行,同时程序继续运行后续代码。例如: <syntaxhighlight lang="javascript"> console.log("开始"); setTimeout(() => console.log("异步操作"), 1000); console.log("结束"); // 输出: // 开始 // 结束 // 异步操作(1秒后) </syntaxhighlight> == 事件循环(Event Loop) == JavaScript通过'''事件循环'''实现异步。其工作原理如下: <mermaid> graph TD A[调用栈] -->|执行| B[同步任务] B --> C[任务完成] D[任务队列] -->|事件循环| A E[Web APIs] -->|回调| D </mermaid> 1. 同步任务在'''调用栈'''中执行 2. 异步任务交给'''Web APIs'''处理(如setTimeout、fetch等) 3. Web APIs完成后将回调放入'''任务队列''' 4. '''事件循环'''在调用栈为空时将任务队列的回调推入调用栈执行 == 回调函数 == 最早的异步实现方式是'''回调函数'''——将函数作为参数传递给异步操作,完成后调用它。 <syntaxhighlight lang="javascript"> function fetchData(callback) { setTimeout(() => { callback("数据加载完成"); }, 1000); } fetchData((message) => { console.log(message); // 1秒后输出:"数据加载完成" }); </syntaxhighlight> === 回调地狱问题 === 多层嵌套回调会导致代码难以维护(称为"回调地狱"): <syntaxhighlight lang="javascript"> getUser(id, (user) => { getPosts(user.id, (posts) => { getComments(posts[0].id, (comments) => { console.log(comments); // 嵌套层级过深 }); }); }); </syntaxhighlight> == Promise == ES6引入的'''Promise'''提供了更优雅的异步处理方式。Promise有三种状态: * '''pending''': 初始状态 * '''fulfilled''': 操作成功完成 * '''rejected''': 操作失败 === 基本用法 === <syntaxhighlight lang="javascript"> const promise = new Promise((resolve, reject) => { setTimeout(() => { const success = true; if (success) { resolve("操作成功"); } else { reject("操作失败"); } }, 1000); }); promise .then((result) => console.log(result)) // "操作成功" .catch((error) => console.error(error)); </syntaxhighlight> === Promise链 === Promise可以通过链式调用解决回调地狱: <syntaxhighlight lang="javascript"> function getUser(id) { return new Promise(/*...*/); } function getPosts(userId) { return new Promise(/*...*/); } getUser(123) .then(user => getPosts(user.id)) .then(posts => console.log(posts)) .catch(error => console.error(error)); </syntaxhighlight> == async/await == ES2017引入的'''async/await'''语法让异步代码看起来像同步代码: <syntaxhighlight lang="javascript"> async function fetchData() { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); console.log(data); } catch (error) { console.error("请求失败:", error); } } fetchData(); </syntaxhighlight> === 工作原理 === * '''async'''函数总是返回Promise * '''await'''会暂停函数执行,直到Promise解决 * 错误可以通过try/catch捕获 == 实际应用案例 == === 案例1:数据获取 === <syntaxhighlight lang="javascript"> async function loadUserProfile(userId) { const [user, posts] = await Promise.all([ fetch(`/users/${userId}`), fetch(`/users/${userId}/posts`) ]); return { user: await user.json(), posts: await posts.json() }; } </syntaxhighlight> === 案例2:动画序列 === <syntaxhighlight lang="javascript"> function animate(element, duration) { return new Promise((resolve) => { element.animate([...], duration).onfinish = resolve; }); } async function runAnimations() { await animate(element1, 1000); await animate(element2, 500); await animate(element3, 1500); } </syntaxhighlight> == 性能考虑 == 异步操作虽然不阻塞主线程,但仍需注意: * 过多并行请求可能导致内存问题 * 微任务(Promise)优先于宏任务(setTimeout)执行 * 长时间运行的同步代码会延迟异步回调执行 使用以下公式计算异步操作的理论完成时间: <math> T_{total} = T_{queue} + T_{execution} </math> 其中: * <math>T_{queue}</math> 是任务在队列中的等待时间 * <math>T_{execution}</math> 是实际执行时间 == 总结 == JavaScript异步编程的发展历程: # 回调函数 → Promise → async/await 关键要点: * 理解事件循环机制 * 优先使用async/await而非回调 * Promise适合处理一次性异步操作 * 错误处理是异步编程的重要部分 通过掌握这些基础概念,您将能够构建高效、响应迅速的JavaScript应用程序。 [[Category:编程语言]] [[Category:JavaScript]] [[Category:Javascript异步编程]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)