解决一则诡异的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)系列从入门到精通开发教程汇总(持续更新中) ==================================================================== 版权归作者所有,未经允许,请勿转载。 ==========================================...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...