# Js 回调函数
Js 回调函数
文章目录
- Js 回调函数
- 回调函数的定义和使用
- 回调函数的常见用途
- 异步操作
- 事件处理
- 回调函数的优点和缺点
- 优点
- 缺点
- 回调地狱
- 解决回调地狱的方法
- 使用 Promise
- 使用 async/await
- 应用
- 函数式编程中的回调函数
- 高阶函数
- 函数柯里化
- 异步编程中的回调函数
- 回调函数的错误处理
- 传递错误参数
- 使用 Promise 和`async/await`
回调函数是一种作为参数传递给另一个函数的函数,它在特定的事件发生或某个操作完成后被调用。
回调函数的定义和使用
sayHellow函数接收一个回调函数作为参数。在函数内部执行一些操作后,调用了传递进来的回调函数。
<!DOCTYPE html>
<button onclick="test1()">回调函数测试</button>
<html>
<body><script type="text/javascript">function sayHellow(msg, callback) {alert(msg)if (typeof callback === "function") {callback(msg);}}function one(msg) {alert("回调函数执行结果:" + msg)}function test1() {sayHellow('你好张三', one);sayHellow('你好李四', function () {alert('匿名函数实现回调')})}</script>
</body>
</html>
回调函数的常见用途
异步操作
- 在
JavaScript中,很多操作是异步的,比如网络请求、文件读取等。 - 回调函数在处理异步操作时非常有用。例如,使用
XMLHttpRequest进行网络请求时,可以在请求完成后调用回调函数来处理响应数据。
事件处理
-
在处理用户交互事件(如点击按钮、鼠标移动等)时,回调函数可以在事件发生时执行相应的操作。
-
例如,给一个按钮添加点击事件监听器,当按钮被点击时,回调函数会被调用。
document.getElementById('myButton').addEventListener('click', function() {console.log('按钮被点击了!');
});
回调函数的优点和缺点
优点
- 灵活性:可以根据不同的需求传递不同的回调函数,实现不同的行为。
- 异步处理:非常适合处理异步操作,确保在操作完成后执行特定的逻辑。
缺点
- 回调地狱:当多个异步操作依赖于彼此的结果时,可能会导致回调函数嵌套过多,使代码难以阅读和维护。
- 错误处理困难:在复杂的回调函数链中,错误处理可能变得复杂。
回调地狱
- 当多个异步操作依赖于彼此的结果时,可能会导致回调函数嵌套过多,形成所谓的"回调地狱"
doSomethingAsync(function() {doAnotherAsyncThing(function() {doYetAnotherAsyncThing(function() {// 更多嵌套...});});
});
解决回调地狱的方法
使用 Promise
Promise是一种用于处理异步操作的对象,它可以避免回调地狱,并提供了一种更清晰的方式来处理异步代码。- 例如,可以使用
then方法链式调用多个异步操作,每个操作返回一个Promise。
function doSomethingAsync() {return new Promise(function(resolve, reject) {setTimeout(function() {console.log('异步操作 1 完成');resolve();}, 1000);});
}function doAnotherAsyncThing() {return new Promise(function(resolve, reject) {setTimeout(function() {console.log('异步操作 2 完成');resolve();}, 1000);});
}// 使用 then 方法调用链
doSomethingAsync().then(doAnotherAsyncThing).then(function() {console.log('所有异步操作完成');});
使用 async/await
async/await是基于Promise的语法糖,它使异步代码看起来更像同步代码,更加易读和易于维护。- 例如,可以使用
async函数和await关键字来等待异步操作完成。
async function performAsyncOperations() {// 等到 doSomethingAsync() 方法执行结束再执行后面的await doSomethingAsync();// 等 doAnotherAsyncThing() 执行完成后再执行后面的 await doAnotherAsyncThing();console.log('所有异步操作完成');
}performAsyncOperations();
应用
函数式编程中的回调函数
高阶函数
- 数组的
map、filter和reduce等方法都是高阶函数,它们接收一个回调函数作为参数,用于对数组中的每个元素进行操作。
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map(function(number) {return number * 2;});
console.log(doubledNumbers); // [2, 4, 6, 8, 10]
map方法接收一个回调函数作为参数,该回调函数将数组中的每个元素乘以2,并返回一个新的数组。
函数柯里化
add函数接收一个参数a,并返回一个新的函数,该函数接收参数b并返回a + b的值。回调函数在这里被用于延迟计算,直到所有的参数都被提供。
<!DOCTYPE html>
</html>
<script>function add(a) {return function (b) {return a + b;};}const addOne = add(5);console.log(addOne(3)); // 8
</script>
异步编程中的回调函数
async和await是ES2017引入的语法糖,用于简化异步操作的处理。
回调函数的错误处理
传递错误参数
- 回调函数通常接收一个错误参数作为第一个参数,用于在发生错误时通知调用者。如果没有错误发生,这个参数通常为
null。 - 例如,下面的代码展示了如何在异步操作中处理错误:
function asyncOperation(callback) {setTimeout(function() {const error = null;const result = 'success';// 返回错误callback(error, result);}, 1000);
}asyncOperation(function(err, result) {if (err) {console.error(err);} else {console.log(result);}
});
asyncOperation函数模拟了一个异步操作,在操作完成时调用回调函数,并传递一个错误参数和一个结果参数。调用者可以根据错误参数的值来决定如何处理结果。
使用 Promise 和async/await
Promise和async/await提供了一种更简洁的方式来处理错误。- 在
Promise中,可以使用catch方法来处理拒绝的Promise,在async/await中,可以使用try/catch块来捕获异步操作中的错误。
// 返回 promise
function asyncOperation() {return new Promise((resolve, reject) => {setTimeout(() => {const error = null;const result = 'success';if (error) {reject(error);} else {resolve(result);}}, 1000);});
}async function executeAsyncOperation() {try {// 等待 asyncOperation 返回结果const result = await asyncOperation();console.log(result);} catch (err) {console.error(err);}
}// 调用 executeAsyncOperation()
executeAsyncOperation();
asyncOperation函数返回一个Promise,在异步操作完成时,根据是否有错误来决定是resolve还是reject这个Promise。- 在
executeAsyncOperation函数中,使用async/await来调用asyncOperation函数,并使用try/catch块来捕获可能发生的错误。
相关文章:
# Js 回调函数
Js 回调函数 文章目录 Js 回调函数回调函数的定义和使用回调函数的常见用途异步操作事件处理 回调函数的优点和缺点优点缺点 回调地狱解决回调地狱的方法使用 Promise使用 async/await 应用函数式编程中的回调函数高阶函数函数柯里化 异步编程中的回调函数回调函数的错误处理传…...
COOLSHELL文章:从Code Review 谈如何做技术【阅读笔记】
从Code Review 谈如何做技术原文链接:https://coolshell.cn/articles/11432.html#google_vignette 工程师需要有责任心和修养,不是做出来就了事,而是要做漂亮。 这也是山寨和工业的区别,只以做出来为标准是劳动密集型的装配生产线…...
3.1.1 ReactOS系统中二叉树创建一个MEMORY_AREA节点
二叉树中创建一个MEMORY_AREA节点: 二叉树中创建一个MEMORY_AREA节点: MmCreateMemoryArea() 参数AddressSpace是MADDRESS SPACE结构指针,所指向的数据结构代表着一个进程的用 户空间。 参数BaseAddress是个指针,用来给定和返回内…...
三、Linux 安装全攻略
Linux 安装全攻略 在当今的科技时代,Linux 操作系统以其稳定性、安全性和高度的可定制性而备受青睐。本文将详细介绍 Linux 的安装过程,包括关键步骤和下载资源获取方式,帮助你顺利踏上 Linux 之旅。 一、为什么选择 Linux Linux 有许多优…...
Ansible自动化工具
一、Ansible概述 1.1 什么是Ansible Ansible 是一个开源的自动化工具,用于配置管理、应用程序部署和任务自动化。它让你可以通过编写简单的 YAML 文件(剧本,Playbooks),轻松管理和配置多个服务器。Ansible 的特点是无…...
Flutter Container组件
Over the past few years, I’ve been fortunate to collaborate with interior designers, and there’s a distinct flair to their approach to crafting captivating interiors. It’s not just about arranging furniture randomly; they meticulously plan layouts, sele…...
IPv6 DNS简介
IPv6网络中的每台主机都是由IPv6地址来标识的,用户只有获得待访问主机的IPv6地址,才能够成功实现访问操作。对于用户来讲,记住主机的IPv6地址是相当困难的,因此设计了一种字符串形式的主机命名机制,这就是域名系统。用…...
【Python-AI篇】数据结构和算法
1. 算法概念 1.1 什么是数据结构 存储,组织数据的方式 1.2 什么是算法 实现业务目的的各种方法和思路算法是独立的存在,只是思想,不依附于代码和程序,可以使用不同语言实现(java,python,c&a…...
VideoCLIP-XL:推进视频CLIP模型对长描述的理解
摘要 对比语言-图像预训练(CLIP)已被广泛研究并应用于众多领域。然而,预训练过程中对简短摘要文本的重视阻碍了CLIP理解长描述的能力。在视频方面,这个问题尤为严重,因为视频通常包含大量详细内容。在本文中ÿ…...
【vue】vue-router_ vue3路由管理器
代码获取 vue-router_ vue3路由管理器 ⼀、基本介绍 1. 单⻚应⽤程序介绍 1.1 概念 单⻚应⽤程序:SPA(Single Page Application)是指所有的功能都在⼀个HTML⻚⾯上实现 1.2 具体⽰例 单⻚应⽤⽹站: ⽹易云⾳乐 https://music.163.com/ 多⻚应⽤⽹…...
昇思MindSpore进阶教程--Diffusion扩散模型(上)
大家好,我是刘明,明志科技创始人,华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享,如果你也喜欢我的文章,就点个关注吧 正文 关于扩散模型(Diffusi…...
Nginx:proxy_pass指令
proxy_pass 指令在 Nginx 中是实现反向代理和负载均衡的重要指令。 一. 反向代理 在反向代理的场景下,proxy_pass 指令用于将接收到的请求转发给另一个后端服务器。后端服务器地址可以是 IP 地址加端口、域名加端口、或者一个完整的 URL。 注意事项 proxy_pass …...
【AI学习】Mamba学习(十):HiPPO总结
前面用五篇文章陆续学了HiPPO框架。 这里再进行一下总结。 总结 HiPPO,高阶多项式投影,high-order polynomial projection operators 为了解决从序列数据中建模和学习的问题,尤其是长序列,十万甚至百万长度的序列,使…...
AI编程新纪元:Cursor与V0引领的技术变革
#1024程序员节 | 征文# AI编程新纪元:Cursor与V0引领的技术变革 作为一名SAP业务顾问,虽然我懂一些ABAP开发,但是我对于前后端开发是完全不懂的,我一直对前后端开发怀有浓厚兴趣,总想着自己能开发出一些好玩的东西&…...
python——类
问:小编为什么突然开始发python?难道C语言你不行了? 废话少说,让我们进入python中的类的学习!! (一)基本知识 (1)掌握类的概念 1、类的定义: 即…...
走廊泼水节——求维持最小生成树的完全图的最小边权和
题目 思考 代码 #include <bits/stdc.h> using namespace std; const int N 6010; const int M N; int p[N], sz[N]; struct edge{int a;int b;int c;bool operator < (const edge& v) const{return c < v.c;} }e[M]; int find(int x) {if(p[x] ! x) p[x] …...
LC:动态规划-买卖股票
文章目录 121. 买卖股票的最佳时机122. 买卖股票的最佳时机 II714. 买卖股票的最佳时机含手续费309. 买卖股票的最佳时机含冷冻期 121. 买卖股票的最佳时机 链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/description/ 使用贪心,…...
FLINK SQL 任务参数
在Flink SQL任务中,参数配置对于任务的性能和稳定性至关重要。以下是对运行时参数、优化器参数和表参数的详细解析: 一、运行时参数 运行时参数主要影响Flink作业在执行过程中的行为。以下是一些关键的运行时参数: 并行度(Para…...
HCIP——以太网交换安全(四)DHCP Snooping
目录 一、DHCP Snooping的知识点 二、DHCP Snooping实验拓扑 三、总结 一、DHCP Snooping的知识点 1.1、DHCP snooping 概述: ①DHCP Snooping使能DHCP的一种安全特性,用于保证DHCP客户端从合法的DHCP服务端获取IP地址。DHCP服务器记录DHCP客户端IP…...
k8s worker 节点关机 sts 管理的 pod 无法迁移
背景 1.28.2 版本 k8s 中的一台 worker 节点内存异常,需要关机换内存,正好可以测试一下 pod 的迁移。 发现 deployment 管理的 pod 是能够重新创建飘到其他节点上的,但是 statefulset 管理的 pod 一直处于 Terminating 状态无法迁移&#…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
