11<script setup lang="ts">
2- import { onMounted , ref , watch } from ' vue'
2+ import { onBeforeUnmount , onMounted , ref , watch } from ' vue'
33import { renderKaTeXInWorker } from ' ../../workers/katexWorkerClient'
44
55const props = defineProps <{
@@ -13,20 +13,43 @@ const props = defineProps<{
1313
1414const mathBlockElement = ref <HTMLElement | null >(null )
1515let hasRenderedOnce = false
16+ let currentRenderId = 0
17+ let isUnmounted = false
18+ let currentAbortController: AbortController | null = null
1619
1720// Function to render math using KaTeX
1821function renderMath() {
19- if (! props .node .content || ! mathBlockElement .value )
22+ if (! props .node .content || ! mathBlockElement .value || isUnmounted )
2023 return
2124
22- renderKaTeXInWorker (props .node .content , true , 3000 )
25+ // cancel any previous in-flight render
26+ if (currentAbortController ) {
27+ currentAbortController .abort ()
28+ currentAbortController = null
29+ }
30+
31+ // increment render id for this invocation; responses from older renders are ignored
32+ const renderId = ++ currentRenderId
33+ const abortController = new AbortController ()
34+ currentAbortController = abortController
35+
36+ renderKaTeXInWorker (props .node .content , true , 3000 , abortController .signal )
2337 .then ((html ) => {
38+ // ignore if a newer render was requested or component unmounted
39+ if (isUnmounted || renderId !== currentRenderId )
40+ return
41+ if (! mathBlockElement .value )
42+ return
2443 mathBlockElement .value .innerHTML = html
2544 hasRenderedOnce = true
2645 })
2746 .catch (() => {
47+ // ignore if a newer render was requested or component unmounted
48+ if (isUnmounted || renderId !== currentRenderId )
49+ return
2850 if (! mathBlockElement .value )
2951 return
52+ // show raw fallback when we never successfully rendered before or when loading flag is false
3053 if (! hasRenderedOnce || ! props .node .loading ) {
3154 mathBlockElement .value .textContent = props .node .raw
3255 }
@@ -42,6 +65,13 @@ watch(
4265onMounted (() => {
4366 renderMath ()
4467})
68+
69+ onBeforeUnmount (() => {
70+ // prevent any pending worker responses from touching the DOM
71+ isUnmounted = true
72+ // increment id so any in-flight render is considered stale
73+ currentRenderId ++
74+ })
4575 </script >
4676
4777<template >
0 commit comments