解决一则诡异的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 中的异常处理机制。
相关文章:
解决一则诡异的javascript函数不执行的问题
有个vue 音乐播放器项目,由于之前腾讯的搜索接口没法用了,于是改成了别家的搜索接口。 但是由于返回数据结构不一样,代码重构的工作量还是挺大的:包括数据请求,数据处理,dom渲染,处理逻辑都进行…...
汽车安全的未来:毫米波雷达在碰撞避免系统中的角色
随着科技的飞速发展,汽车安全系统变得愈加智能化,而毫米波雷达技术正是这一领域的亮点之一。本文将深入探讨毫米波雷达在汽车碰撞避免系统中的关键角色,以及其对未来汽车安全的影响。 随着城市交通的拥堵和驾驶环境的变化,汽车安全…...
体感互动游戏研发虚拟场景3D漫游
体感互动游戏是一种结合虚拟现实(VR)或增强现实(AR)技术的游戏,允许玩家以身体动作和姿势来与游戏互动。这种类型的游戏通常需要特殊的硬件设备,例如体感控制器、摄像头或传感器,以捕捉玩家的动…...
微信小程序获取手机号(2023年10月 python版)[无需订阅]
技术栈: 1. 微信开发者工具中的调试基础库版本:3.1.2。 2. 后台:django。 步骤: 1. 首先在后台django项目的定时任务中增加一个下载access_token函数,并把得到的access_token保存在数据库中(其实随便哪里…...
Linux下设置网关以及网络相关命令
一、临时设置网关 查看当前路由表:route -n设置网关:route add default gw <路由器的网关IP> 注意:系统重启时,这些更改将不生效 二、永久设置网关 列出可用网络连接:nmcli connection show设置网关&#x…...
linux三剑客~sed命令的使用
1.工作原理: sed是一种流编辑器,它是文本处理中非常有用的工具 能够完美的配合正则表达式使用,处理时,把当前处理的行存储在临时缓冲区中,称为模式空间,接着用sed命令处理缓冲区中的内容 处理完成后&…...
virtualBox虚拟机安装多个+主机访问虚拟机+虚拟机访问外网配置
目的:本机安装3个虚拟机 一、虚拟机安装:Oracle VM VirtualBox (https://www.virtualbox.org/)源代码可下载,且免费使用 1、https://www.virtualbox.org/ 进入网站中Download 模块选择与自己电脑系统相应的下载包下载即可 如果安装过程报错如…...
正点原子嵌入式linux驱动开发——Linux按键输入
在前几篇笔记之中都是使用的GPIO输出功能,还没有用过GPIO输入功能,本章就来学习一下如果在Linux下编写GPIO输入驱动程序。正点原子STM32MP1开发板上有三个按键,就使用这些按键来完成GPIO输入驱动程序,同时利用原子操作来对按键值进…...
java--强制类型转换
类型范围大的数据或者变量,直接赋值给小范围的变量,会报错 1.强制类型转换 强行将类型范围大的变量、数据赋值给类型范围小的变量 2.强制类型转换在计算机中的执行原理 解释说明1:a是int类型有8个字节32位,然后在执行下一行代码…...
java后端调用接口Basic auth认证
该方法接收一个JSON字符串参数phoneNum 内容: {"phone":"13712312312"} 然后解析参数中的手机号,作为data去调用URL接口,接收接口返回的复合JSON并解析,拿到想要的数据public String queryUserResumeURLIn…...
App爬虫之强大的Airtest的操作总结
App爬虫之强大的Airtest的操作总结 App爬虫之强大的Airtest的操作总结 # Python使用该框架需要安装的依赖库 pip install airtest pip install poco pip install pocouifrom airtest.core.api import * from airtest.cli.parser import cli_setup from poco.drivers.android.…...
MODBUS-TCP转MODBUS-RTU通信应用(S7-1200和串口服务器通信)
在学习本博客之前,大家需要熟悉MODBUS-TCP和MODBUS-RTU通信,这2个通信的编程应用,大家可以查看下面文章链接: MODBUS-RTU通信 MODBUS-RTU通信协议功能码+数据帧解读(博途PLC梯形图代码)-CSDN博客MODBUS通信详细代码编写,请查看下面相关链接,这篇博客主要和大家介绍MODB…...
开源贡献难吗?
本文整理自字节跳动 Flink SQL 技术负责人李本超在 CommunityOverCode Asia 2023 上的 Keynote 演讲,李本超根据自己在开源社区的贡献经历,基于他在贡献开源社区过程中的一些小故事和思考,如何克服困难,在开源社区取得突破&#x…...
seata的TCC模式分析
TCC是 Try- Confirm-Cancel 这3个名词的首字母简称,是一个2阶段提交的变体思路。 Try:对资源的检查和预留; Confirm: 确认对预留资源的消耗,执行业务操作; Cancel:预留资源的释放; TCC的事务…...
常用linux命令【主要用于日志查询,目录切换】
Xshell设置登录 :主机,端口号 用户身份验证:账号/密码登录脚本:等待-[hcuserserver02 ]$ 发送-cd /data/logs/pl-capital-processer-server/$(date “%Y-%m-%d”) 下方-添加按钮/编辑 发送文本,追加 grep --color de…...
Python学习基础笔记七十六——Python装饰器2
装饰器,英文名字decorator。 我们开发Python代码的时候,经常碰到装饰器。 通常被装饰后的函数,会在原来的函数的基础上,增加一些功能。 通常装饰器本事也是一个函数,那么装饰器是怎么装饰另外一个函数的呢?…...
生产环境解决用户登录问题的实践
目录 1 前言2 问题提出3 问题分析和解决4 技术分析和改进5 结语 1 前言 在开发管理软件平台为美术馆时,我们致力于提供一个多系统集成平台,其中包括艺术品管理、志愿者管理和数字资产管理等子系统。为了确保用户享有流畅的体验,我们采用了一…...
通讯协议学习之路:QSPI协议理论
通讯协议之路主要分为两部分,第一部分从理论上面讲解各类协议的通讯原理以及通讯格式,第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN;视频会发布在bilibili(UID:399951374) 一、…...
pip安装修改镜像源
使用pip安装报错时,例如 raise ReadTimeoutError(self._pool, None, “Read timed out.”) pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host‘download.pytorch.org’, port443): Read timed out 可以选择国内的镜像源,如下…...
QCC51XX-QCC30XX系列开发教程(实战篇) 之 12.4-空间音频手机侧和耳机侧接口设计时序图
查看全部教程开发请点击:全网最全-QCC51xx-QCC30xx(TWS)系列从入门到精通开发教程汇总(持续更新中) ==================================================================== 版权归作者所有,未经允许,请勿转载。 ==========================================...
FastDDS XML配置实战:从HelloWorld到可配置QoS的完整迁移指南
FastDDS XML配置实战:从硬编码到灵活部署的工程化演进 在分布式系统开发中,数据分发服务(DDS)因其高效的实时通信能力被广泛应用于工业物联网、自动驾驶等领域。作为DDS规范的实现之一,FastDDS凭借其出色的性能和灵活性赢得了开发者青睐。本…...
信创协同办公价格与成本:这样选,性价比直接拉满!
“一套信创协同办公到底多少钱?”“是按人头收费,还是按项目打包算?”“前期买着便宜,后期维护会不会无底洞?”不管是政企单位采购,还是企业选型,这三个问题几乎是所有人的核心顾虑。毕竟信创办…...
不伤身的酒是智商税?这款轻养新标杆打破偏见
1.当“喝酒伤身”成为共识,谁在挑战这个铁律?中国人喝酒的历史,几乎和文明史一样长。但“喝酒伤身”这四个字,也像影子一样,从未离开过酒桌。每一次举杯,耳边总有人念叨:“少喝点”“伤肝”“伤…...
Pixel Script Temple 效果进阶:YOLOv11目标识别引导的精准构图像素画
Pixel Script Temple 效果进阶:YOLOv11目标识别引导的精准构图像素画 1. 效果亮点预览 当像素艺术遇上目标检测技术,会碰撞出怎样的火花?最新发布的YOLOv11模型与Pixel Script Temple的结合,让像素画创作进入了精准构图的新阶段…...
VRCT终极指南:3步实现VRChat跨语言实时翻译,打破虚拟社交障碍
VRCT终极指南:3步实现VRChat跨语言实时翻译,打破虚拟社交障碍 【免费下载链接】VRCT VRCT(VRChat Chatbox Translator & Transcription) 项目地址: https://gitcode.com/gh_mirrors/vr/VRCT 您是否曾在VRChat的国际房间中,面对来自…...
Git-RSCLIP入门到精通:从基础地物识别到复杂场景分析全流程解析
Git-RSCLIP入门到精通:从基础地物识别到复杂场景分析全流程解析 1. 遥感智能分析的新利器 在遥感图像分析领域,传统方法往往需要大量标注数据和复杂的模型训练流程。Git-RSCLIP的出现彻底改变了这一局面,它基于先进的SigLIP架构,…...
Graphormer在计算毒理学中的应用:预测hERG通道抑制活性的完整建模流程
Graphormer在计算毒理学中的应用:预测hERG通道抑制活性的完整建模流程 1. 项目概述 Graphormer是一种基于纯Transformer架构的图神经网络,专门为分子图(原子-键结构)的全局结构建模与属性预测而设计。该模型在OGB、PCQM4M等分子…...
革新性PDF可视化标记技术:从原理到实践的全方位解析
革新性PDF可视化标记技术:从原理到实践的全方位解析 【免费下载链接】obsidian-pdf-plus PDF: the most Obsidian-native PDF annotation & viewing tool ever. Comes with optional Vim keybindings. 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-…...
毕业设计实战:基于Java+MySQL的教务管理系统设计与实现指南
毕业设计实战:基于JavaMySQL的教务管理系统设计与实现指南 在开发“基于JavaMySQL的教务管理系统”毕业设计时,曾因课程报名表未通过学生ID与课程ID双外键关联踩过关键坑——初期仅设计报名编号、报名时间等基础字段,未与学生表、课程表建立关…...
YOLOv8人脸检测实战:如何将WIDER Face数据集玩出新花样?结合OpenCV分类提升准确率
YOLOv8人脸检测实战:WIDER Face数据集与OpenCV分类的融合优化 人脸检测技术早已从实验室走向实际应用,但误检问题始终困扰着开发者。上周团队在商场部署的人脸统计系统,竟将广告牌上的明星照片全部计入客流——这种尴尬促使我们重新思考单阶段…...
