即使组件被销毁 VUEJS,组件内部的逻辑仍然执行

Logic inside component still execute even after component is destroyed VUEJS

我有一个组件,我在其中使用 while 循环每 3 秒调用一次 API 来检查状态。

async download()
{
 while(true) //->
 {
   await sleep(300);
   console.log("still executing");
   const status = await this.$store.dispatch("myaction",Id);
   if(status.property === 2)
    break;
 }
}

Destroy()
{
 console.log("component destroyed");
}

问题是当我离开组件时,我可以在控制台中看到它正在被销毁,因为它正在调用 Destroy() 挂钩并打印我的日志语句。但另一方面,它仍然在 while 循环中打印我的控制台语句。难道不是 运行 因为组件被销毁还是因为 await sleep?

只是补充信息。调度 returns 100 毫秒内的承诺。

如何防止它在我离开组件时不立即执行?

您应该开始使用 setTimeoutsetIntervalwhile(true) 并不是真正应该在 JavaScript 中使用(在 high-level 上下文中)的构造,因为它基本上无限期地执行并且尽可能快。您必须确保 break; 它在将来的某个地方停止执行。

此外,没有办法对此类代码进行垃圾回收。你可以摧毁你想要的一切,但你的 while(true) 构造将继续循环。

你可能会做的是:

// Some component
{
    data() {
        return {
            interval_id: undefined,
        }
    },
    methods: {
        someMethod() {
            // Execute some code every 3 seconds (3000ms).
            this.interval_id = setInterval(() => {
                executeSomeCode();
            }, 3000);
        },
        executeSomeCode() {
            console.log('Executed');
        }
    },
    // ...
    Destroy() {
        if(this.interval_id) {
            clearInterval(this.interval_id);
        }
    }
}

另请注意,您的代码中存在拼写错误:Destory -> Destroy

框架不可能影响您自己的代码在 download 函数中的执行方式。该函数防止组件实例在运行时变为 garbage-collected,这是内存泄漏可能如何工作的演示。开发人员有责任在卸载时停止执行:

unmounted() {
  this.isUnmounted = true;
},
...
async download() {
  while(!this.isUnmounted) {
    await sleep(300);
    if (this.isUnmounted)
      break;
    ...

可能需要在多个地方使用检查以减少不需要的工作量。这就是它在原生承诺和 async..await 情况下的工作方式。在使用可观察对象或可取消承诺和生成器的组合时,可能还有其他方法可以提前中断流程。