Просмотр исходного кода

Always wait for buffered ops before compiling (#23336)

GitOrigin-RevId: 1e586979897fb01378e449fe9dc9c7d269de83bb
Alf Eaton 1 год назад
Родитель
Сommit
8406807552

+ 4 - 11
services/web/frontend/js/features/pdf-preview/util/compiler.js

@@ -5,6 +5,7 @@ import { debounce } from 'lodash'
 import { trackPdfDownload } from './metrics'
 import { enablePdfCaching } from './pdf-caching-flags'
 import { debugConsole } from '@/utils/debugging'
+import { signalWithTimeout } from '@/utils/abort-signal'
 
 const AUTO_COMPILE_MAX_WAIT = 5000
 // We add a 2 second debounce to sending user changes to server if they aren't
@@ -86,17 +87,9 @@ export default class DocumentCompiler {
     }
 
     try {
-      if (
-        typeof AbortSignal.any === 'function' &&
-        typeof AbortSignal.timeout === 'function'
-      ) {
-        await this.openDocs.awaitBufferedOps(
-          AbortSignal.any([
-            this.signal,
-            AbortSignal.timeout(PENDING_OP_MAX_WAIT),
-          ])
-        )
-      }
+      await this.openDocs.awaitBufferedOps(
+        signalWithTimeout(this.signal, PENDING_OP_MAX_WAIT)
+      )
 
       // reset values
       this.setChangedAt(0) // TODO: wait for doc:saved?

+ 25 - 0
services/web/frontend/js/utils/abort-signal.ts

@@ -0,0 +1,25 @@
+export const supportsModernAbortSignal =
+  typeof AbortSignal.any === 'function' &&
+  typeof AbortSignal.timeout === 'function'
+
+export const signalWithTimeout = (signal: AbortSignal, timeout: number) => {
+  if (supportsModernAbortSignal) {
+    return AbortSignal.any([signal, AbortSignal.timeout(timeout)])
+  }
+
+  const abortController = new AbortController()
+
+  const abort = () => {
+    window.clearTimeout(timer)
+    signal.removeEventListener('abort', abort)
+    abortController.abort()
+  }
+
+  // abort after timeout has expired
+  const timer = window.setTimeout(abort, timeout)
+
+  // abort when the original signal is aborted
+  signal.addEventListener('abort', abort)
+
+  return abortController.signal
+}