解决一则诡异的javascript函数不执行的问题-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

有个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);
      });
    },

问题解决

总结

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

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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: JavaScriptJava

“解决一则诡异的javascript函数不执行的问题-CSDN博客” 的相关文章