如何免费开自己的网站,seo计费系统源码,柳州最好的网站推广公司,怎么查看Wordpress根目录异步编程基础 本文主要介绍回调函数#xff0c;Promise#xff0c;aysnc/wait这三种异步机制#xff0c;顺便说说axios#xff0c;还有不要和我一样弄混ajax与异步的关系#xff0c;正常走学校教学路线的人#xff0c;可能第一个接触的就是ajax#xff0c;刚好又不懂Promiseaysnc/wait这三种异步机制顺便说说axios还有不要和我一样弄混ajax与异步的关系正常走学校教学路线的人可能第一个接触的就是ajax刚好又不懂所以可能和我一样弄混。除上述知识点其他都是凑字数的。 注意AJAX不是前端异步的代名词
反正我学的时候老是容易搞混
混淆原因 早期 “AJAX” 一词被广泛用于指代 “异步网络请求”因为在 AJAX 诞生初期2005 年左右它是前端实现异步通信的主要方式因此很多人将 “异步” 与 “AJAX” 直接关联AJAX 只是异步编程在 “浏览器与服务器通信” 场景下的应用 前端异步机制分类通用机制与应用场景
一、异步编程通用机制按实现方式分类
机制类型核心原理典型实现优缺点回调函数通过函数参数传递异步结果异步任务完成后调用回调函数setTimeout、XMLHttpRequest 旧版- 简单直接- 缺点回调地狱、代码可读性差Promise用状态机管理异步操作pending/fulfilled/rejected支持链式调用fetch()、Promise.resolve()- 避免回调嵌套- 统一错误处理.catch()- 代码更清晰async/awaitPromise 的语法糖以同步写法处理异步自动返回 Promiseasync function await- 最接近同步代码的写法- 错误处理用 try...catch更符合直觉Generator通过迭代器Iterator分段执行异步任务需手动调用 next() 推进流程function* gen() { yield ... }- 控制粒度更细- 缺点需手动管理流程现代开发中较少使用
二、异步机制应用场景按功能场景分类
场景类型核心功能技术实现典型案例网络通信浏览器与服务器的异步数据交互不阻塞页面fetch、XMLHttpRequest、WebSocket- 动态加载数据如商品列表- 实时聊天WebSocket异步双向通信定时任务按指定时间间隔执行异步操作setTimeout、setInterval- 轮询获取数据如天气更新- 动画帧控制requestAnimationFrame用户交互响应鼠标、键盘等用户操作异步执行回调事件监听addEventListener- 按钮点击、滚动加载更多- 表单实时验证并行计算开启后台线程处理密集计算不阻塞主线程UI 渲染Web Worker、SharedWorker- 图片处理、大数据排序- 游戏物理引擎计算文件操作异步读取/写入文件主要在 Node.js 环境fs.readFile、fs.writeFile- 读取配置文件- 写入日志数据
1. 异步编程有什么用
有点后端基础的都知道异步是在多线程学习时才涉及到的概念那么前端的这个异步有什么作用
这里敲黑板
前端的异步它并非解决多线程问题它只是在表面上达到了多线程一样的效果而是为了在单线程环境下实现非阻塞操作。
JavaScript主线程单线程的特性决定了同步操作会阻塞渲染所以提出了异步的概念解决这个问题 JavaScript 是一种单线程语言运行在浏览器的主线程中。这意味着在任何时刻JavaScript 代码只能在一个线程上运行。无论是同步代码还是异步代码它们都是在同一个线程上执行的。 总之别把前端的异步和后端的异步扯上一点关系当一个全新的东西去学就好了。 举个前端异步例子
前端同步就像你洗澡得先等热水器把水烧热才能开始洗。要是热水器坏了或者水烧得很慢你就只能干等着啥也干不了。 前端异步就好比你一边烧热水一边看电视。热水烧着就烧着你也不用一直盯着可以先做别的事。等水烧好了你再洗澡就行。这样你的时间就被充分利用了不会因为等待热水而浪费时间整个过程也更高效。 2. 异步机制
异步机制 允许在等待I/O网络请求/文件读取时释放主线程保持页面渲染与处理流畅。它的核心目的是让程序在等待某个任务完成时能够继续执行其他任务而不是像同步代码那样一直阻塞等待。
所有异步机制最终都基于浏览器的 事件循环Event Loop 机制执行这是 JS 异步编程的核心基础。
3. 前端有几种异步机制
前端中常见的异步机制包括回调函数、Promise、async/await、和 Generator。其中Promise 和 async/await 是目前最常用和推荐的异步处理方式。
本文重点介绍前四种异步机制最后一种说实话我还没真正用过。
3.1 回调函数Callback
回调函数是最传统的异步处理方式通过将一个函数作为参数传递给另一个函数并在异步操作完成时调用这个回调函数。
示例代码
//函数定义fetchData 函数定义时接受一个函数式的参数 callback。这个callback并没有具体定义和普通参数一样只是提供一个位置。
//这个参数是一个函数意味着 fetchData 可以在执行过程中调用这个传入的函数。
function fetchData(callback) {//这里是故意的延时操作模拟服务器2秒后加载回数据setTimeout(() {console.log(数据加载完成);callback(数据);}, 2000);
}fetchData((data) {console.log(接收到数据, data);
});回调体现
函数定义在 fetchData 函数内部使用 setTimeout 模拟了一个异步操作例如从服务器加载数据。当这个异步操作完成时即 2 秒后通过 callback(“数据”) 调用了传入的回调函数并传递了 “数据” 作为参数。
回调函数的使用在 fetchData 函数调用时 传入了一个箭头函数 (data) { console.log(接收到数据, data); } 作为回调函数。 所以这个fetchData执行的步骤其实是这样的 1.进入setTimeOut函数内部 2.延时2秒 4. 输出数据加载完成日志 5.执行callback函数参数而此时callback函数参数是(data) { console.log(“接收到数据”, data); } 6. 输出接收到数据数据日志 顺带解释一下这里的箭头函数
箭头函数基础知识点复习
箭头函数是ES6引入的简洁函数语法用符号定义通常省略function关键字和return适用于单行表达式或需要绑定外层this的场景。
例如传统函数 function(a, b) { return a b; } 可简化为箭头函数 (a, b) a b
关键特性
无独立this继承父级作用域的this不能用作构造函数无prototype属性适合回调函数或方法缩写 回调特点总结
简单直接适用于简单的异步操作。但容易出现“回调地狱”Callback Hell即嵌套过多的回调函数代码难以维护。 3.2 Promise
Promise 是一种更现代的异步处理方式它代表了一个异步操作的最终完成或失败及其结果值其实写它的时候也会使用回调函数只不过一个传统回调函数实现异步更像嵌套使用后者是链式调用代码可读性会好一丢丢并且Promise有一定的定义和方法方便处理异常情况。
注意这个目前Promise并没有特别合适的中文翻译所以和别人讨论异步涉及它时直接说这个单词就好了。
Promise状态
Promise 有三种状态
pending初始状态既不是成功也不是失败。 fulfilled操作成功完成。 rejected操作失败Promise任何一个环节出现错误都会切换到这个状态当然也可以手动reject让Promise切换成rejected状态
状态一旦改变从 pending 变为 fulfilled 或 rejected就会被固化不会再变化。
Promise状态处理
Promise 提供 .then()、.catch() 和 .finally() 处理结果
.then() 可处理 fulfilled 或 rejected 状态通过第二个回调参数可以忽略处理rejected状态的处理大多数人更习惯使用.catch来处理rejected状态。.catch() 是专门处理 rejected 状态的语法糖等价于 .then(null, onRejected)。.finally() 无论状态如何都会执行用于清理操作。
示例代码
function fetchData() {return new Promise((resolve, reject) {setTimeout(() {console.log(数据加载完成);resolve(数据);// 如果出错可以用 reject(错误信息);}, 2000);});
}fetchData().then((data) {console.log(接收到数据, data);}).catch((error) {console.error(发生错误, error);});Promise特点总结
避免了回调地狱代码更加清晰。提供了错误处理机制通过 .catch()。可以通过 Promise.all() 等方法同时处理多个异步操作。
3.3 async/await
async 和 await 是 ES2017ES8引入的 JavaScript 语法用于简化 Promise 的使用让异步代码看起来更像同步代码。它们本质上是 Promise 的语法糖但提供了更直观的写法。
用我自己的角度来理解你想让异步操作就在函数前面加个await如果某个函数里加了await那就必须使用aysnc保证它异步操作生效。并且await要使用try和catch进行异常捕获。
哪里需要等待异步结果就在哪里加 await加了 await 的函数必须用 async 修饰为了安全用 try…catch 捕获可能的错误。
aysnc
async 用于声明一个异步函数它有两个特点
自动返回 Promise无论函数内部是否显式返回 Promiseasync 函数的返回值都会被包装成 Promise。支持 awaitasync 函数内部可以使用 await 关键字等待 Promise 完成。
await
await 只能在 async 函数内部使用它的作用是
暂停函数执行等待 Promise 被解决fulfilled 或 rejected。返回 Promise 的结果如果 Promise 成功则返回其结果值如果失败则抛出错误需用 try…catch 捕获。
示例代码
// 模拟一个异步操作如网络请求
function simulateNetworkRequest() {console.log(开始请求数据...);// 返回一个 Promise表示异步操作return new Promise((resolve) {// 使用 setTimeout 模拟 2 秒的网络延迟setTimeout(() {console.log(服务器已返回数据);resolve(用户信息和文章列表); // 数据加载完成传递结果}, 2000);});
}// 使用 async 声明异步函数
async function fetchData() {console.log(进入 fetchData 函数);// await 会暂停当前函数的执行等待 Promise 完成const result await simulateNetworkRequest();// 这行代码会在 Promise 成功后才执行console.log(fetchData 函数继续执行);return result;
}// 主函数
async function main() {console.log(程序开始执行);try {console.log(等待数据加载...);// 调用异步函数并等待结果const data await fetchData();// 这行代码会在 fetchData 完全执行完毕后才运行console.log(成功获取数据, data);} catch (error) {console.error(获取数据失败, error);}console.log(程序执行结束);
}// 启动主函数
main();aysnc/wait特点总结
代码更简洁更接近同步代码的写法。使用 try...catch 可以方便地捕获错误。需要与 Promise 结合使用。 3.4 Generator生成器
Generator 是一种可以暂停和恢复执行的函数虽然它本身不是直接用于异步操作但可以通过手动控制暂停和恢复来实现异步效果。不过Generator 的使用相对复杂且不如 async/await 方便。
示例代码
function* fetchData() {console.log(开始加载数据);yield new Promise((resolve) {setTimeout(() {console.log(数据加载完成);resolve(数据);}, 2000);});
}const generator fetchData();
const promise generator.next().value;
promise.then((data) {console.log(接收到数据, data);
});特点总结
可以暂停和恢复函数执行。需要手动管理暂停点和恢复逻辑。使用场景较少通常被 async/await 替代。
异步实现方法总结
前端中常见的异步机制包括回调函数、Promise、async/await和 Generator已经基本介绍了一遍。说实话没有实践这些理论都很难理解就算理解了也真得很难形象地描述出来。 其中Promise 和 async/await 是目前最常用和推荐的异步处理方式因为它们提供了更简洁、更易读的代码风格和强大的错误处理机制。 4 axios基于Promise的HTTP客户端
前文已经说过Promise和async/await 是目前最常用和推荐的异步处理方式这么常用又好用的功能自然有人会想办法使用技术和它进行对接。
axios是一个流行的基于Promise的HTTP客户端可以用于浏览器和Node.js环境。它提供了丰富的功能如拦截请求和响应、取消请求、自动转换JSON数据等。
4.1 axios的基本用法
axios的核心API返回Promise因此可以与async/await无缝集成
// GET请求
axios.get(/api/users).then(response console.log(response.data)).catch(error console.error(error));
// POST请求
axios.post(/api/users, { name: John }).then(response console.log(创建成功:, response.data)).catch(error console.error(创建失败:, error));4.2 axios与async/await的结合
axios与async/await结合使用可以简化异步请求处理
async function getUserData(userId) {try {const userResponse await axios.get(/api/users/${userId});const user userResponse.data;const postsResponse await axios.get(/api/users/${userId}/posts);const posts postsResponse.data;return { user, posts };} catch (error) {console.error(获取数据失败:, error);throw error;}
}4.3 axios的优势
Promise基础所有请求都返回Promise可以与async/await完美结合拦截器可以拦截请求和响应添加自定义逻辑如认证、日志记录取消请求支持请求取消避免不必要的处理自动转换JSON自动将响应数据转换为JavaScript对象浏览器兼容性支持老版本浏览器提供polyfill 5 技术对比与选择指南
5.1 Promise与async/await的区别
特性Promiseasync/await语法链式调用 .then()类同步代码错误处理.catch()try/catch可读性可能形成回调地狱更接近自然语言适用场景简单异步操作复杂异步流程基础是异步处理的基础建立在Promise之上
5.2 axios与原生fetch的对比
特性axiosfetchPromise基础是是自动JSON转换是否拦截器支持不支持错误处理自动处理网络错误需要手动检查浏览器兼容广泛支持现代浏览器取消请求支持需要polyfill
5.3 链式调用与同步异步的结合
在实现异步链式调用时需要考虑
同步链式调用方法依次执行每个方法返回this异步链式调用方法中包含异步操作需要特殊处理执行顺序Promise链式调用使用.then()连接多个异步操作async/await链式调用使用await等待异步操作完成 6. 最佳实践与注意事项
6.1 异步编程的最佳实践
错误处理始终处理异步操作中的错误特别是在使用async/await时并行操作对于不依赖彼此的异步操作使用Promise.all并行执行取消机制对于长时间运行的操作实现取消机制避免资源浪费避免过度使用await对于并行操作await会串行化执行影响性能
6.2 性能优化建议
缓存结果对于重复的异步操作考虑缓存结果限制并发对于大量异步操作限制并发数量避免资源耗尽使用Web Workers对于CPU密集型操作考虑使用Web Workers合理使用Promise.allSettled当需要等待多个操作完成而不关心个别失败时
6.3 代码组织建议
分离异步逻辑将异步操作封装在单独的函数中使用中间件模式对于复杂的异步流程考虑使用中间件模式避免嵌套使用async/await减少回调嵌套文档注释为异步函数添加清晰的文档注释说明返回的Promise状态 7 异步编程总结与未来展望
异步编程是现代Web开发的核心技能Promise、async/await、axios和链式调用等技术共同构成了JavaScript异步编程的完整生态。这些技术各有优势合理组合使用可以构建出高效、可维护的应用程序。 随着JavaScript语言的发展异步编程模型将继续演进。异步迭代器、异步生成器等新特性为异步编程提供了更多可能性。同时TypeScript等工具也为异步代码提供了更好的类型支持进一步提高了开发效率和代码可靠性。 掌握这些异步编程技术不仅能够解决当前的开发挑战也为应对未来更复杂的异步场景奠定了坚实基础。通过不断实践和总结开发者可以形成自己高效的异步编程模式构建出更优秀的Web应用。