【面试题】 javaScript 进阶之路 --- 《加深理解回调函数》

news2024/10/7 18:24:56

 给大家推荐一个实用面试题库

1、前端面试题库 (面试必备)            推荐:★★★★★

地址:前端面试题库

 

一. 函数

  1. 回调函数的基本概念我之前的文章虽然有些过,但是为了引入下文,在这里还是简单再提一嘴。我们先看一下 MDN 的解释。 

  2. 什么意思呢?还拿我们上一章节的例子。一个 setTimeout 里,隔了1秒去控制台打印一个 conole.log() 。

  3. 让我们拆解一下。我们仔细看下面的一行代码,你发现了吗?我只不过是把声明一个箭头函数,变为了定义一个匿名函数。其实这两种写法的所产生的效果是一模一样的。(请暂时不要考虑箭头函数和普通函数的区别)


    在这种情况下,上面的匿名函数箭头函数统称为函数 setTimeout 的回调函数。你一定需要明白的事情就是 setTimemout 也是一个函数! 单独的函数是无法被叫做回调函数的,回调函数的概念是相互的。所以更确切的说法应该是:

首先这里的箭头函数和匿名函数作为 setTimout 的参数,然后在 setTimout 内部被调用,最后箭头函数和匿名函数才被称为 setTimout 的回调函数。

  1. 我发现其实有很多新手是没有搞懂函数不同的声明方式,所以才导致你们迷惑的。我们这里先来讲一下函数常用的三种定义方式。 


    在这里虽然这三个函数的执行结果是一样的,但是它们的区别是不小的。使用 function 关键字声明一个函数。被叫做函数声明。 而下面的两种方法是被叫做函数表达式

  2. 虽然在使用方法上我们都是通过 "()" 去调用,但是其实它们还是有差别的。其中最重要的一个差别就是,使用函数声明定义的一个函数,该变量会被 js 解析器提升到代码开始执行之前。而使用函数表达式定义的函数则不会被提升。什么意思呢? 


    你会发现,我们竟然可以在定义 hello 函数之前去使用这个函数。而下面两个函数都报出了在赋值之前调用的错误。

  3. 在这里我们再延伸一个知识点。我们在定义 hello 函数之前,首先定义一个 变量 name


    虽然这里看起来 name 是在 hello 函数之前声明的,但是 hello 这个变量的声明其实是在变量 name 之前的。

  4. 其原因用简单的描述就是:js 解析器会在到你这个.js 文件后,会优先去查找使用 function 声明的函数名称,然后把这些函数名保存在一个对象中,并且提前创建一个引用来-->指向这个函数体。 具体细节还需读者自主查询,本文重点不在这里。

  5. 如果你读懂了上面的几个环节,那么我觉得这种写法你同样应该明白了。 


    那么我们趁热打铁,开启下一篇章。

二. 数据处理方式

  1. 我们都知道函数是为了帮助我们完成一些复杂的逻辑运算,可以反复调用的,并且函数是可以传递参数的。 

     比如上面的函数,允许我们传递两个数字类型的变量,然后该函数会把这两个数字的和返回给我们。

  2. ok,上面的内容很简单,我想大家应该都明白。如果我们日常和后端打交道的数据传输没有延迟,那么自然而然我们对数据处理起来就会非常方便。什么意思呢?假设我们 向后端发送请求获得数据 ,这一过程是一瞬间完成的,那么我们就可以顺着我们的想法从上往下写非常顺畅。 

     如上面刚写的的函数一样,你可以理解为我们向后端服务器请求了一个数据,数据一瞬间就返回了,那么们就可以把这个 data 给返回出去。然后在下面用一个变量去接受一下,随之进行一些运算。

  3. 就如上一篇文章讲的那样。很遗憾的是,我们在进行一些可能需要一定时间才可以完成的任务的时候,不可能是同步完成的,因为一行代码而阻塞后面整段代码的执行是非常不可取的事情。

  4. 这里我们来简单模拟一个场景。 

     我们定义了一个普通对象 data 来模拟后端即将传递给我们的数据。我们假设这个数据的可能需要花费 1s 的时间才能返回。我们可能自然而然的想到,那不是和之前一样嘛,在 setTimeout 里返回不就行了吗。

    你可以先思考一下上面的这段代码,userData 会拿到正确的 data 值吗?

  5. 非常遗憾的是,我们是无法在同步的代码里第一时间拿到异步函数的返回值的。 


    那么造成上面的代码结果的原因是为什么?为什么是 undefined 呢?我们一步一步分析。

三. 理清思路

  1. 当下面画黄线的代码被执行的时候。紧接着下一步我们就需要马上跳进 getData 的函数体中去分析。

  2. 进到这个函数里,首先就是执行 setTimeout 函数。 (我在这里再再再亿次强调,setTimeout 本身就是一个普通函数,没什么特别的。) 

  3. 但是 setTimeout 函数会把接收的回调函数给推送到任务队列里去排队。什么?你没看见回调函数?这不就是文章最开头说的函数的声明方式之一箭头函数吗?怎么这么快就忘了?自觉翻回上面去再看一遍⏰。

  4. 紧接着 getData函数 执行完毕,看一眼,函数本身没有返回值,那么默认返回值为 undefined

  5. 这里需要特别注意! 我们如果在这里写了 return语句 ,这样才能算是 getData函数的 返回值。


    而在我们的 data 却是 setTimout 的回调函数的返回值,你能拿到才怪。

  6. 那怎么办呢?我们继续往下看。

四. 回调函数

  1. 别着急往下看,经过上面的三个环节,我们先做个小测试🎁。 


    上面这段代码你看懂了吗?(下面是执行结果) 
    如果你对执行结果不是特别清楚,没关系。到这一步我只希望你能读懂下面这行代码,至少对于写法上,很清楚的知道为什么可以这样写

    如果你暂时还没搞懂,那么我强烈建议你至少回过头再品味一下第一个标题 函数,这次要细读。

  2. 如果你读懂了,恭喜你🎉,你距离理解这个名词更近了一步。接下来我们稍微改造一下代码。 

  3. 上面这段代码乍一看很玄乎,别着急,我们慢慢分析。首先 modifyData函数 是我们提前设定好的一个处理后端数据的函数。(前提是如果我们能拿到后端给我们的数据)

  4. 既然我们没有办法在同步函数里拿到 data 后再去处理,那么我们就干脆提前给后端代码函数 getData 一个参数。

一个我们提前设定好的处理函数。当 setTimeout 的回调函数拿到数据后,就帮我们执行这个函数,也就是 modifyData 函数。然后把 data 作为参数传递给 modifyData函数

  1. 我们在 setTimout 的回调函数中打印一下修改前后的值。 

     

  2. 我们会发现,我们之后的代码都在回调函数里去处理的话,就能完美实现需求。也就是后端传过来的数据我们可以拿到了,并且可以处理成我们想要的数据了。

结语

在这里我们就先不引入解回调地狱的概念了了,我害怕都的读者确实会绕迷糊。 我会在放在手写 Promise 之前,引入这个概念。 希望读者可以细细体会上面的代码,一旦学会这些概念,你会看到和之前不一样的 js 世界🎁。

给大家推荐一个实用面试题库

1、前端面试题库 (面试必备)            推荐:★★★★★

地址:前端面试题库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/66090.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

苹果电脑ntfs如何打开硬盘?mac能读取的硬盘格式

如今,使用Mac电脑的用户越来越多,但是不少用户却面临着一个问题,那就是Mac无法正常读写自己的NTFS格式的外置硬盘,硬盘上面保存着很多重要的文件数据,想要进行复制或者是编辑等,压根没有办法在Mac电脑上进行…

axios和SpringMVC数据交互(一维二维数组,JSON/form形式,@RequestBody/@RequestParam)

目录需求环境准备前端后端成功实现的案例以JSON形式发送double数组以JSON形式发送对象,对象中有数组以JSON形式发送对象,对象中有二维数组以x-www-form-urlencoded形式发送一维数组需求 前端或postman发送数组,后端controller做为入参接收 …

汽车专场 | 新能源汽车动力电池PACK CAE分析实例解读

一、PACK为什么需要CAE分析? PACK是新能源汽车最重要的组成部分,可称之为心脏,电池系统需要满足汽车运营条件下的苛刻力学环境的要求。按照传统研发方式,设计-样包-测试-优化-样包-测试,反复循环,这种传统…

学完高性能计算后的发展怎么样?

高性能计算行业是指从事高性能计算相关性质的生产、服务的单位或个体的组织结构体系的总称。深刻认知高性能计算行业定义,对预测并引导高性能计算行业前景,指导行业投资方向至关重要。 一、什么是高性能计算? 高性能计算指通常使用很多处理…

音视频学习(十四)——rtsp详解

概念 rtsp(Real Time Streaming Protocol,RFC2326),实时流传输协议,是TCP/IP协议体系中的一个应用层协议。 该协议主要规定了一对多应用程序如何有效地通过IP网络传送多媒体数据。RTSP体系结位于RTP和RTCP之上&#…

etsy账号被封的原因有哪些?

Etsy之所以让人又爱又恨,是因为它的流量大,但缺点是规则限制,尤其是对于中国卖家。根据各大社交媒体的留言和评论,大多数电商人最关心Etsy关店的问题。   为什么Etsy会被封号?首先,我们需要了解封号的原因…

高压放大器的输入和输出阻抗为啥是50欧的

选择高压放大器的时候,经常会看到有些高压放大器的输入和输出阻抗都是50欧,今天就来说说高压放大器和无处不在的50欧姆,来聊聊它们的关系。 电子测量仪器在使用的时候会出现电子信号幅度突然加倍或者减少一半的情况,原因是几乎所有…

用echarts实现柱状图

目录前言:什么是 Echarts 插件柱状图成品展示步骤:柱状图代码:前言: 大家都知道,一般情况下,想要使用前端设置一个 柱状图 需要使用 canvas 画布进行编写,不仅代码多,逻辑处理麻烦&…

搭建Nacos集群

nacos的默认端口是8848,但是他还占用了另外两个接口:9848、9849。因此,在单机配置集群时,不可使用三个连续的端口,否则会导致 gRPC端口冲突。 端口与主端口(8848)偏移量作用98481000客户端gRPC…

7.javase_数组1

一. 数组定义格式 格式1:数据类型[] 变量名; 范例:int[] arr; 格式2:数据类型 变量名[]; 范例: int arr[];二. 数组初始化方式 1.1静态初始化:【初始化时指定每个数组元素的初始值,由系统决定数组长度】格…

ARFoundation系列讲解 - 89 适配华为机型

一、简介 使用 ARCore 开发安卓应用的时候,由于谷歌的制裁和鸿蒙系统的不兼容,导致华为大部分机型无法使用,而国内使用华为设备的群体占比较大的比例所以兼容华为设备是一个绕不过的坎。这个章节我们将学习使用 HuaweiAREngine 结合 ARFoundation 兼容使用来解决这个问题。 …

职业教育数字化成行业发展新方向

2022年,职业教育正迎来新的风口。随着与普通教育同等重要的地位得到确认,职业教育将肩负起建设与我国经济结构转型需求相匹配的人才供给的重任,在社会服务业、战略新兴行业等各大领域中大放异彩。 一、职业教育是什么? 1、职业教育定义 联合国教科文组织认为职业教育(Vocat…

PID控制器的远程设定点功能及其应用

摘要:远程设定点功能是超高精度PID控制器的重要拓展功能之一,其在实际自动控制中有着广泛的应用。本文详细介绍了远程设定点的功能和操作设置过程,同时还介绍了远程设定点功能在跟踪控制、串级控制和比值控制中的具体应用。 原文阅读&#x…

争议不断的AI绘画,靠啥成为了顶流?

今年以来,AIGC迅速崛起。所谓AIGC,即AI-Generated Content,指的是利用人工智能来生成内容,被认为是继专业产出内容(PGC)、用户产出内容(UGC)后的新型内容创作方式。不久前掀起热议的…

品牌化、跨境电商、专注细分赛道,平台助力品牌快速出海

国内国外产品都面临着日趋激烈的竞争,卖家越来越意识品牌的效应的重要作用。在竞争激烈的大环境之下,卖家必须采取有效的产品品牌营销策略来提高自身产品的市场竞争力。品牌营销在一定程度上可以增强产品在激烈的市场竞争的影响力。同时,口碑…

【DL】Windiws10系统下安装CUDA和CUDNN实践教程

Windiws10系统下安装CUDA和CUDNN实践教程(手把手系列,不错过任何一个环节): 一、查看需要的CUDA版本 点击开始菜单栏右侧的放大镜,输入NVIDIA 然后点击NVIDIA Control Panel,进入NVIDIA控制面板 点击管理3D设置->系统信息 弹出以下界面框 点击组件,就可以看到驱动对…

工业CT检测技术及工业CT基本组成

工业CT基本组成 由重建CT图像的基本过程出发,我们可以想象一下组成一台工业CT设备的基本要求:它应该能够量 X射线穿透被检物体以后射线的强度,同时能够完成X射线机-探测器系统与被检测物体之间的扫描运动,从而获得重建CT图像所需的…

如何将u盘两个分区合并?u盘怎么合并一个区

U盘是我们日常工作中应用得很广泛的便携式存储设备,具有体积小、便携易带、容量大、随插随拔等优势。为了方便存储数据,不少的用户都会对U盘分区,那么,如何将u盘两个分区合并? 一、合并U盘分区的应用与说明 合并U盘分…

Java高效率复习-MySQL下篇

前言 本文章的语言描述会比上篇多一些 数据库的创建修改与删除 标识符命名规则 数据库名、表名不得超过30个字符,变量限制为29个必须只能包含A-Z,a-z,0-9,_等63个字符数据库名、表名、字段名等对象名中间不要包含空格同一个My…

【Unity编辑器扩展】GF_HybridCLR自定义Toolbar, 一键出包/打热更扩展工具

GF_HybridCLR是基于GameFramework HybridCLR的一款工具链完善,工作流简洁的游戏框架。拥有标准高效的开发工作流,开箱即用,适用于快速研发。 出包时经常遇到忘记刷新配置表、忘记重新打AB包等等,接入HybridCLR每次打热更包也需要…