解决一则诡异的javascript函数不执行的问题

有个vue 音乐播放器项目,由于之前腾讯的搜索接口没法用了,于是改成了别家的搜索接口。

但是由于返回数据结构不一样,代码重构的工作量还是挺大的:包括数据请求,数据处理,dom渲染,处理逻辑都进行了大规模的修改。最后改的差不多了。

还有最后一个功能:搜索推荐,当鼠标滚动时,会不断加载更多记录,也就是searchMore(实际上就是分页加载), 直到全部记录加载完成为止,此时就不能再滚动了。如下图:

 那么这里需要一个逻辑:判断searchMore搜索更多的时候是否已经加载到最后一条记录了

这里使用的是一个checkMore函数:

    // 判断全部歌曲是否已经加载完毕checkMore(data) {console.log("checkmore收到数据==》",data)   if (   // result是当前已经加载数据的列表, data.songCount是该搜索关键字的总记录数   this.result.length >= data.songCount) {// 使用hasMore作为列表数据是否全部加载完毕的标识this.hasMore = false;}},

这里使用hasMore作为列表数据是否全部加载完毕的全局标识。

而checkMore函数是嵌入到searchMore函数的, 通过控制hasMore的标识来决定是否发起request请求。

    searchMore() {   console.log("searchMore 执行了。。。。。")if (!this.hasMore) {return;}this.page++;const data = {query: this.query,limit: this.perpage,offset: (this.page - 1) * this.perpage,};search(data.query,data.limit,data.offset).then((res) => {      if ( res.code === HTTP_OK && res.result.songs.length > 0 ) {this._normalizeSongs(res.result.songs).then((resp) => {this.result = this.result.concat(resp);});          }this.checkMore(res.result);});},

但是这里非常奇怪的是,checkMore似乎失效了,因为无论滚动多少次,都会一直发起http请求。

很明显这不是我的预期,到底是哪里出现了问题呢?

我仔细检查了checkMore的逻辑,并没有发现任何问题。

然后也做了断点调试,也没有发现任何线索。

于是终于祭起了终极console.log大法!终于发现了关键的线索:

checkMore函数总共只执行了2次,searchMore执行力3次

而按照代码逻辑:首次search的时候checkMore会执行一次,然后以后每次searchMore都会执行checkMore函数

也就是说: 实际情况是:从第二次滚动(searchMore)开始:checkMore就没再执行了!

 那么是什么原因导致了checkMore没有执行呢?

再看看console的报错信息:

 看到这里终于恍然大悟了:肯定是这里抛出了异常,导致了后面的代码没有执行!

那么res.result.songs.length为什么会抛undined异常呢,看看response就知道了:

 原来: 从第二次searchMore开始,result地下就已经没有songs属性了!

那么res.result.songs就必然是一个undefined了!

所以解决办法有两个:

1. 把checkMore函数放到searchMore函数的第一行(不推荐):

        这样就规避了后面函数的异常所产生的影响。但是这种方法不推荐,因为它没有从根本上解决抛异常的问题

2. 使用object的hasOwnProperty方法去判断对象上是否有某属性,这样就能规避异常的问题

// 判断对象是否有某属性

object.hasOwnProperty("属性名称")

   searchMore() {   console.log("searchMore 执行了。。。。。")if (!this.hasMore) {return;}this.page++;const data = {query: this.query,limit: this.perpage,offset: (this.page - 1) * this.perpage,};search(data.query,data.limit,data.offset).then((res) => {// 注意:如果这里发生了异常,那么后面的this.checkMore是不会执行的,这个是关键!// 所以这里使用hasOwnProperty方法来判断对象是否有某属性,从而不会触发异常if (res.code === HTTP_OK && res.result.hasOwnProperty('songs')) {this._normalizeSongs(res.result.songs).then((resp) => {this.result = this.result.concat(resp);});          }this.checkMore(res.result);});},

问题解决:

总结:

1.不要小看对象取属性带来的undefined异常问题,因为这种异常往往非常隐蔽!很难觉察到它所带来的诡异后果. 如有可能尽量使用hasOwnProperty方法判断属性是否存在!

2.  在 JavaScript 中,如果前面的代码抛出了异常但没有提前捕获,程序将在抛出异常的地方终止执行,则后面的代码将不会执行。如果你使用了try/catch块来捕获异常,并且在catch 块中处理了异常,那么后面的代码才会执行。这是 JavaScript 中的异常处理机制。

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

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

相关文章

Elasticsearch:什么是余弦相似度?

余弦相似度是数据科学、文本分析和机器学习领域的基本概念。 如果你想知道什么是余弦相似度或者它如何在现实世界的应用程序中使用,那么你来对地方了。 本指南旨在让你深入了解相似性是什么、其数学基础、优点及其在不同领域的各种应用。读完本指南后,你…

PHP 变量

变量 变量的声明、使用、释放 变量定义 形式 $ 变量名;严格区分大小写 $name; $Name; $NAME //三个变量不是同一个变量字母、数字、下划线组成,不能以数字开头,不能包含其他字符(空白字符、特殊字符) 驼峰式命名法、下划线式命名法 $first_name; $fi…

在 Visual Studio Code (VS Code) 中设置

在 Visual Studio Code (VS Code) 中设置代理服务器的详细教程如下: 打开 Visual Studio Code。 在顶部菜单栏中,点击 "File"(文件) > "Preferences"(首选项) > "Settings…

IP协议(上)

目录 一、初步认识IP协议 二、认识IP地址 三、协议报头格式 1.报头和有效载荷分离 2.20字节的固定数据 四、网段划分 1.一个小例子 2.认识IP地址的划分 3.数据的传输过程 4.特殊的IP地址 5.通信运营商 (1)通信运营商的作用 (2&a…

如何利用考培系统进行个性化学习和评估

考培系统作为一种现代化的学习和评估工具,可以为学生提供个性化的学习和评估服务。它利用先进的技术和算法,根据学生的学习情况和需求,为其量身定制学习计划,并提供相应的评估反馈。 1. 个性化学习 考培系统通过分析学生的学习情…

javaEE - 2(11000字详解多线程)

一:多线程带来的的风险-线程安全 线程安全的概念:如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的。 当多个线程同时访问共享资源时,就会产生线程安全的风险&am…

【AIGC核心技术剖析】扩大富有表现力的人体姿势和形状估计SMPLer-X模型

富有表现力的人体姿势和形状估计 (EHPS) 将身体、手和面部运动捕捉与众多应用结合起来。尽管取得了令人鼓舞的进展,但当前最先进的方法仍然在很大程度上依赖于有限的训练数据集。在这项工作中,我们研究了将 EHPS 扩展到第一个通用基础模型(称为 SMPLer-X),以 ViT-Huge 作为…

【译】快速开始 Compose 跨平台项目

原文: Compose Multiplatform application 作者:JetBrains 注意 Compose Multiplatform 中的 iOS 部分目前处于 Alpha 状态。以后可能会有不兼容的更改,届时也许需要手动进行迁移。 你可以使用这个模板来开发同时支持桌面、安卓和 iOS 的跨平…

GitHub验证的2FA

一、 起因: GitHub需要双重身份验证 (2FA) 是登录网站或应用时使用的额外保护层。启用 2FA 时,必须使用您的用户名和密码登录,并提供另一种只有您知道或可以访问的身份验证形式。 二、解决: 2.1 这里使用chrome的身份验证插件进…

在emacs中,设置latex的主文档

文档: chapter1.tex chapter2.tex main.tex 在chapter1.tex中,先按下 ctrlc ctrln,再按下ctrlc ctrla,在下方的提示框中输入主文档。

支付宝小程序介入人脸识别(金融级--前端部分)

在这里只做前端部分说明: 详情参考文档:如何通过集成支付宝小程序唤起实人认证服务_实人认证-阿里云帮助中心 操作步骤 调用 API 发起认证。 发起认证服务。 调用 startBizService 接口请求认证。 function startAPVerify(options, callback) {my.call(startBizService, {n…

AWS S3加密

Hello大家好。 在本课时我们将讨论S3加密相关的内容。 S3加密相关是认证考试的一个重要的主题考点,您需要了解亚马逊S3的几种不同类型的加密方式。| 首先是静态数据的加密,静态数据加密是指数据存储在亚马逊S3 数据中心的磁盘上时&#xff0…

stable diffusion和midjourney哪个好

midjourney和stable diffusion哪个好?midjourney和stable diffusion的区别?那么今天就从这2款软件入手,来探索一下他们的功能的各项区别吧,让你选择更适合你的一款ai软件。 截至目前,我们目睹了生成式人工智能工具的在…

Linux —— 网络基础(一)

目录 一,计算机网络背景 二,网络协议初识 三,网络传输基本流程 四,网络中的地址管理 一,计算机网络背景 网络发展 独立模式,计算机之间相互独立;网络互联,多台计算机连接在一起…

【OpenCV实现图片以及视频的读取、显示、保存以及绘图函数】

文章目录 图片视频从文件读取视频保存一个视频绘图函数 图片 OpenCV(Open Source Computer Vision Library)是一个广泛应用于计算机视觉和图像处理领域的开源库。它提供了丰富的图像处理工具和算法,使得开发者能够轻松实现各种图像处理任务。…

科普丨语音芯片烧录流程概述

语音芯片的烧录是将特定的固件或软件加载到芯片中,以使其能够执行特定的语音处理功能。以下是一般的语音芯片烧录过程: 1. 准备固件或软件:开发人员需要编写或获取特定的固件或软件,这些固件或软件包含了语音处理算法和功能的代码…

【周末闲谈】VR新视界,“眼”见未来

个人主页:【😊个人主页】 系列专栏:【❤️周末闲谈】 系列目录 ✨第一周 二进制VS三进制 ✨第二周 文心一言,模仿还是超越? ✨第二周 畅想AR 文章目录 系列目录前言虚拟现实(VR)技术虚拟现实技术的原理虚拟现实技术发…

高精度时间测量(TDC)电路MS1022

MS1022 是一款高精度时间测量电路,内部集成了模拟比 较器、模拟开关、施密特触发器等器件,从而大大简化了外 围电路。同时内部增加了第一波检测功能,使抗干扰能力大 大提高。通过读取第一个回波脉冲的相对宽度,用户可以获 得接…

laravel的默认首页怎么改-laravel框架默认欢迎页面如何修改

laravel的默认首页怎么改 搭建好的laravel的默认首页怎么改 我们有两种改动方式: 第一种修改默认路由: 下一步是要移除Laravel应用程序默认的欢迎页路由。这个路由可以在routes/web.php文件的顶部找到,看起来类似于以下代码: …

OpenGL —— 2.7、绘制多个自旋转的贴图正方体(附源码,glfw+glad)

源码效果 C源码 纹理图片 需下载stb_image.h这个解码图片的库,该库只有一个头文件。 具体代码: vertexShader.glsl #version 330 corelayout(location 0) in vec3 aPos; layout(location 1) in vec2 aUV;out vec2 outUV;uniform mat4 _modelMatrix; …