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

news2024/11/17 3:51:36

有个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.coloradmin.cn/o/1113472.html

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

相关文章

C++算法:二叉树的序列化与反序列化

#题目 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。 请设计一个算法来实现二叉树的序列化与反序列化。…

golang的json转pb验证

基于这篇文章的最后一个代码进行验证。 https://blog.csdn.net/mijichui2153/article/details/133894403?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22133894403%22%2C%22source%22%3A%22mijichui2153%22%7D 1、准备 &…

gs_moment

ps:仅共学习,自用。

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; …

抽象数据库

在刚刚的文章中,完成了无范式到三级范式的过程 : 遵循原子性。即,表中字段的数据,不可以再拆分。 在满足第一范式的情况下,遵循唯一性,消除部分依赖。即,表中任意一个主键或任意一组联合主键&#xff0c…

计算几何+2sat:1020T3

http://cplusoj.com/d/senior/p/SS231019C 我们进行这样的转化 则0/1必选一个,2/3必选一个 那么就变成一个2sat问题 两三角形有交,则一个选,一个不能选 对角三角形一个选,一个不选。一个不选,一个选 三角形不合法…

体感互动游戏研发虚拟场景3D漫游

体感互动游戏是一种结合虚拟现实(VR)或增强现实(AR)技术的游戏,允许玩家以身体动作和姿势来与游戏互动。这种类型的游戏通常需要特殊的硬件设备,例如体感控制器、摄像头或传感器,以捕捉玩家的动…

spring cloud alibaba 集成seata

1.启动服务端 1.下载 seata-server-1.4.2 2.创建数据库 DROP DATABASE IF EXISTS ry-seata;CREATE DATABASE ry-seata DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;USE ry-seata;-- ---------------------------…

Java操作Python数据交互最佳实践

Java操作Python最佳实践 1、Java与Python的互操作性2、Java调用Python脚本及数据交互2.1、准备工作2.2、执行一段Python代码2.3、执行Python文件脚本2.4、执行Python文件中的指定方法2.5、执行含有第三方库的Python文件3、附录1、Java与Python的互操作性 在当今的软件开发领域,…

Linux服务器下装anaconda | 配置深度学习环境 | Pycharm连接远程服务器-经验总结

0 前言 推荐2个工具 WinSCP 一个 Windows 环境下使用的 SSH 的开源图形化 SFTP 客户端。同时支持 SCP 协议。它的主要功能是在本地与远程计算机间安全地复制文件,并且可以直接编辑文件。 WindTerm 一个多平台开源免费的终端软件,用于连接服务器 一…

Redis 主从复制,哨兵,集群——(3)集群篇

目录 1. 前篇回顾 2. Redis 集群是什么? 3. Redis 集群的优点 4. Redis 集群的槽位概念 5. 什么是分片? 6. 如何找到给定key的分片? 7. 分片槽位的设计有什么好处? 8. key映射到节点的三种解决方案 8.1 哈希取余分区 8.…

SortedSet 和 List 异同点

SortedSet 在 Java 的整个集合体系中,集合可以分成两个体系,一个是 Collection 存储单个对象的集合,另一个是 k-v 结构的 Map 集合。 SortedSet 是 Collection 体系下 Set 接口下的派生类,而 Set 集合的特征是不包含重 复的元素的…

【UE】纯蓝图实现:在游戏运行时设置关键点,然后让actor沿着关键点移动

前言 在上一篇博客(【UE】两步实现“从UI中拖出Actor放置到场景中”)中我们已经实现了如何从UI拖拽生成Actor ,本篇博客在此基础上要实现的是:从UI中拖出车,再从UI中拖出关键点,点击“开始移动”按钮后,车会沿着关键点移动,具体效果如下所示。 效果 步骤 1. 首先创建…

WMS透明仓库:实现仓储的全方位可视化与优化

一、WMS透明仓库的定义与特点 1. WMS透明仓库的定义:WMS透明仓库是一种基于信息技术的仓库管理系统,通过实时数据采集、分析和可视化,将仓库内外的物流流程、库存状态、人员活动等信息以透明的方式展示给相关利益方。 2. 实时数据采集&…

RCD负载箱的安全性能和认证标准有哪些?

RCD负载箱的安全性能和认证标准主要包括以下几个方面:RCD负载箱应符合国家标准或国际标准的防护等级要求,通常情况下,RCD负载箱应具备防护等级为IP54或更高级别,以确保在恶劣的环境条件下仍能正常工作。 RCD负载箱的绝缘电阻应满足…

Python+unittest接口自动化测试

首先配置好开发环境,下载安装Python并下载安装pycharm,在pycharm中创建项目功能目录。以下是项目的目录结构: common: 1 2 3 4 5 6 7 8 9 ——configDb.py:这个文件主要编写数据库连接池的相关内容,本项目…

suricata匹配从入门到精通(五)----二次开发保护规则库

0x00 背景 开源的suricata资源包是没有做加密处理,如果想要保护资源包,需要二次开发修改suricata源码。 本文基于suricata6.0.1 版本https://github.com/OISF/suricata/archive/refs/tags/suricata-6.0.1.zip二开。 0x01 实践 通过debug,跟规则处理相关需要修改2个地方。…

iPhone垃圾清理器:AnyMP4 iOS Cleaner for mac

AnyMP4 iOS Cleaner 是一款功能强大的iOS设备清理工具,旨在帮助用户轻松管理和优化iOS设备上的存储空间。该工具支持iPhone、iPad、iPod等设备,可以有效地清理无用的缓存、日志、文稿等,以释放存储空间。它还具有一键清理功能,能够…

二维码智慧门牌管理系统开发:高效解决道路数据难题

文章目录 前言一、二维码智慧门牌管理系统的创新性二、道路数据采集与处理三、二维码智慧门牌管理系统的优势 前言 在当今这个信息化社会,数据的准确性和及时性对于各种项目的成功实施至关重要。尤其是在智慧城市建设中,道路数据是不可或缺的基础性数据…

Spring Boot学习笔记

SpringBoot特征 特征 创建独立的 Spring 应用程序 直接嵌入 Tomcat、Jetty 或 Undertow(无需部署 WAR 文件) 提供“入门”依赖项以简化构建配置 尽可能自动配置 Spring 和 第三方库 提供生产就绪功能,例如指标、健康检查和外部化配置 完…