Skip to content

Commit 7a026f4

Browse files
committed
fix(useScript): singleton abort promise
Fixes nuxt/scripts#291
1 parent 8fd2a67 commit 7a026f4

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

packages/schema/src/script.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ export interface ScriptInstance<T extends BaseScriptApi> {
3333
/**
3434
* @internal
3535
*/
36-
_triggerAbortController?: AbortController
36+
_triggerAbortController?: AbortController | null
37+
/**
38+
* @internal
39+
*/
40+
_triggerAbortPromise?: Promise<void>
3741
/**
3842
* @internal
3943
*/

packages/unhead/src/composables/useScript.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ export function useScript<T extends Record<symbol | string, any> = Record<symbol
104104
id,
105105
status: 'awaitingLoad',
106106
remove() {
107+
// cancel any pending triggers as we've started loading
108+
script._triggerAbortController?.abort()
109+
script._triggerPromises = [] // clear any pending promises
107110
if (script.entry) {
108111
script.entry.dispose()
109112
syncStatus('removed')
@@ -150,22 +153,33 @@ export function useScript<T extends Record<symbol | string, any> = Record<symbol
150153
script.load()
151154
}
152155
else if (trigger instanceof Promise) {
153-
script._triggerAbortController = script._triggerAbortController || new AbortController()
154156
// promise triggers only work client side
155157
if (head.ssr) {
156158
return
157159
}
160+
if (!script._triggerAbortController) {
161+
script._triggerAbortController = new AbortController()
162+
script._triggerAbortPromise = new Promise<void>((resolve) => {
163+
script._triggerAbortController!.signal.addEventListener('abort', () => {
164+
script._triggerAbortController = null
165+
resolve()
166+
})
167+
})
168+
}
158169
script._triggerPromises = script._triggerPromises || []
159170
const idx = script._triggerPromises.push(Promise.race([
160171
trigger.then(v => typeof v === 'undefined' || v ? script.load : undefined),
161-
new Promise<void>((resolve) => {
162-
script._triggerAbortController!.signal.addEventListener('abort', () => resolve())
163-
}),
164-
]).then((res) => {
165-
res?.()
166-
// remove the promise from the list
167-
script._triggerPromises?.splice(idx, 1)
168-
}))
172+
script._triggerAbortPromise,
173+
])
174+
// OK
175+
.catch(() => {})
176+
.then((res) => {
177+
res?.()
178+
})
179+
.finally(() => {
180+
// remove the promise from the list
181+
script._triggerPromises?.splice(idx, 1)
182+
}))
169183
}
170184
else if (typeof trigger === 'function') {
171185
trigger(script.load)

0 commit comments

Comments
 (0)