vue切换页面,前一个页面的异步方法还在继续执行

一、问题

1.1 背景

有两个vue页面,第一个页面加载了spreadJS的excel组件,并且挂到了window上,在这个页面上其他地方会从后端获取数据,并使用该组件显示到前端。
初始化方法

    initSpread (spread) {
      console.log("初始化页面一的 spreadJS")
      window.mySpread = spread;
   }

加载数据的异步方法返回后执行的方法

window.mySpread.fromJSON(json});

第二个页面的是同样的方式初始化spread并加载数据

1.2 问题

第一个页面加载数据慢,第二个页面加载数据快。
当第一个页面加载的时候,立刻切换到第二个页面,就会发现第二个页面的数据出来后,过了会儿又被第一个页面的数据覆盖了

二、排查并解决

很显然,可以猜测到,是第一个页面的数据返回的慢,把第二个页面的数据覆盖了。通过打印日志,证实了这个猜想,第一个页面的异步方法先执行并查询数据,但是后返回结果并执行window.mySpread.fromJSON(json})的慢,导致数据被覆盖。
那么为什么第一个页面已经切换了,还会继续执行这个方法呢?
这是js的特性 …

2.1 尝试解决

在vue的destroyed里面,把spread给销毁了

  destroyed () {
    if (window.mySpread) {
      window.mySpread.destroy()
    }
  }

并没有解决问题

2.2 解决方法一

我们既然不能让第一个页面的异步方法停止执行,那我们能不能让这个异步方法里面监控到页面已经销毁了,然后直接return,不继续执行 window.mySpread.fromJSON(json})这个方法了呢?
找到了这个方法 this._isDestroyed 如果这个页面被销毁了,则返回true;
那我们可以在执行window.mySpread.fromJSON(json}) 这个方法前先判断一下是否该页面已经被销毁了,如果被销毁了,就不执行下面的方法了

   if(_this && _this._isDestroyed) {
      console.log("如果当前页面已经销毁了,那么就不加载表格");
      return;
   }

经过测试,可以达到效果

2.3解决方法二

为什么会出现第一个页面覆盖了第二个的值的情况呢?猜测是由于使用了window.mySpread 保存spread对象;因为这是个全局对象,会造成累死线程安全的问题?
所以第二个解决方法就是每个页面,挂到不同的name下,比如页面一 window.mySpread1 = spread;页面二 window.mySpread2 = spread; 做一个区分,但是没有实际测试过,有谁测试了可以评论区留言。

你可能感兴趣的:(BUG记录,vue.js,javascript,前端)