beyond-all-reason / bar-lobby

BAR Lobby Client
https://beyond-all-reason.github.io/bar-lobby/
MIT License
33 stars 30 forks source link

Custom battles interval still runs sometimes when not on battles page #181

Closed Jazcash closed 1 year ago

Jazcash commented 1 year ago
  1. Open battle list page
  2. Visit some other page

Expected: Should stop listening for updates to battles, console Actual: Still seeing the lobby query the server for battle updates, as seen in the console

image

Jazcash commented 1 year ago

I found out why this happens. All JS functions run to completion, there is no way to halt the execution of a function once it's begun. The code inside <script setup> blocks is just syntactic sugar for the setup() function in Vue's composition API, which means all the code in the script block will run until completion, regardless of if that component still exists or not.

The problematic code in multiplayer/custom.vue is:

await updateBattleList();

await delay(500);

const intervalId = window.setInterval(updateBattleList, 5000);

onUnmounted(() => {
    window.clearInterval(intervalId);
});

When we navigate away from this view before the updateBattleList and delay promises have resolved, the code keeps executing and the interval is created after the onUnmounted callback. I'm not sure of the best solution to this problem. There's the AbortController API which can be used to cancel promises - utilising that is probably the most correct way.