Adjust lifecycleHooks.setup to allow async callbacks (#2388)

This commit is contained in:
Matthias Metelka 2023-02-22 02:38:58 +01:00 committed by GitHub
parent 09a946574b
commit f604575b41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -11,8 +11,8 @@ type ComponentAPIDestroy<T> = (api: T) => void;
type SetLifecycleHooksAction<T> = (api: T) => void; type SetLifecycleHooksAction<T> = (api: T) => void;
export interface LifecycleHooks<T> { export interface LifecycleHooks<T> {
onMount(callback: ComponentAPIMount<T>): Callback; onMount(callback: ComponentAPIMount<T>): Callback | Promise<Callback>;
onDestroy(callback: ComponentAPIDestroy<T>): Callback; onDestroy(callback: ComponentAPIDestroy<T>): Callback | Promise<Callback>;
} }
/** /**
@ -27,22 +27,25 @@ function lifecycleHooks<T>(): [LifecycleHooks<T>, T[], SetLifecycleHooksAction<T
function setup(api: T): void { function setup(api: T): void {
svelteOnMount(() => { svelteOnMount(() => {
const cleanups: Callback[] = []; const cleanups: Promise<void | Callback>[] = [];
for (const callback of mountCallbacks) { for (const mountCallback of mountCallbacks) {
const cleanup = callback(api); // Promise.resolve doesn't care whether it's a promise or sync callback
cleanups.push(
if (cleanup) { Promise.resolve(mountCallback).then((callback) => {
cleanups.push(cleanup); return callback(api);
} }),
);
} }
// onMount seems to be called in reverse order // onMount seems to be called in reverse order
instances.unshift(api); instances.unshift(api);
return () => { return async () => {
for (const cleanup of cleanups) { for (const cleanup of await Promise.all(cleanups)) {
cleanup(); if (cleanup) {
cleanup();
}
} }
}; };
}); });
@ -50,8 +53,10 @@ function lifecycleHooks<T>(): [LifecycleHooks<T>, T[], SetLifecycleHooksAction<T
svelteOnDestroy(() => { svelteOnDestroy(() => {
removeItem(instances, api); removeItem(instances, api);
for (const callback of destroyCallbacks) { for (const destroyCallback of destroyCallbacks) {
callback(api); Promise.resolve(destroyCallback).then((callback) => {
callback(api);
});
} }
}); });
} }