mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
Improve implementation of asyncRefresh
This commit is contained in:
parent
a9c16a3cd8
commit
75a8b7d318
3 changed files with 67 additions and 34 deletions
|
@ -1,28 +1,30 @@
|
||||||
import { Readable, readable, derived } from "svelte/store";
|
import { Readable, readable, derived } from "svelte/store";
|
||||||
|
|
||||||
export interface AsyncData<T, E> {
|
export interface AsyncData<T, E> {
|
||||||
value: Readable<T | null>,
|
value: Readable<T | null>;
|
||||||
error: Readable<E | null>,
|
error: Readable<E | null>;
|
||||||
pending: Readable<boolean>,
|
pending: Readable<boolean>;
|
||||||
success: Readable<boolean>,
|
success: Readable<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function useAsync<T, E = unknown>(asyncFunction: () => Promise<T>): AsyncData<T, E> {
|
function useAsync<T, E = unknown>(asyncFunction: () => Promise<T>): AsyncData<T, E> {
|
||||||
const promise = asyncFunction();
|
const promise = asyncFunction();
|
||||||
|
|
||||||
const value = readable(null, (set: (value: T) => void) => {
|
const value = readable(null, (set: (value: T) => void) => {
|
||||||
promise.then((value: T) => set(value))
|
promise.then((value: T) => set(value));
|
||||||
})
|
});
|
||||||
|
|
||||||
const error = readable(null, (set: (value: E) => void) => {
|
const error = readable(null, (set: (value: E) => void) => {
|
||||||
promise.catch((value: E) => set(value))
|
promise.catch((value: E) => set(value));
|
||||||
})
|
});
|
||||||
|
|
||||||
const pending = derived([value, error], (_, set) => set(false), true)
|
const pending = readable(true, (set: (value: boolean) => void) => {
|
||||||
const success= derived([value], (_, set) => set(true), false)
|
promise.finally(() => set(false));
|
||||||
|
});
|
||||||
|
|
||||||
return { value, error, pending, success }
|
const success = derived([value], (_, set) => set(true), false);
|
||||||
|
|
||||||
|
return { value, error, pending, success };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useAsync
|
export default useAsync;
|
||||||
|
|
|
@ -1,30 +1,61 @@
|
||||||
import { Readable, derived, get } from "svelte/store";
|
import { Readable, readable, derived } from "svelte/store";
|
||||||
import useAsync, { AsyncData } from "./async";
|
|
||||||
|
|
||||||
interface AsyncRefreshData<T, E> {
|
interface AsyncRefreshData<T, E> {
|
||||||
value: Readable<T | null>,
|
value: Readable<T | null>;
|
||||||
error: Readable<E | null>,
|
error: Readable<E | null>;
|
||||||
pending: Readable<boolean>,
|
pending: Readable<boolean>;
|
||||||
success: Readable<boolean>,
|
success: Readable<boolean>;
|
||||||
loading: Readable<boolean>,
|
loading: Readable<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function useAsyncRefresh<T, E>(
|
||||||
|
asyncFunction: () => Promise<T>,
|
||||||
|
dependencies: [Readable<unknown>, ...Readable<unknown>[]]
|
||||||
|
): AsyncRefreshData<T, E> {
|
||||||
|
const initial = asyncFunction();
|
||||||
|
const promise = derived(dependencies, (_, set) => set(asyncFunction()), initial);
|
||||||
|
|
||||||
function useAsyncRefresh<T, E = unknown>(asyncFunction: () => Promise<T>, dependencies: [Readable<unknown>, ...Readable<unknown>[]]): AsyncRefreshData<T, E> {
|
const value = derived(
|
||||||
const current = derived(
|
promise,
|
||||||
dependencies,
|
($promise, set: (value: T | null) => void) => {
|
||||||
(_, set: (value: AsyncData<T, E>) => void) => set(useAsync<T, E>(asyncFunction)),
|
$promise.then((value: T) => set(value));
|
||||||
useAsync<T, E>(asyncFunction),
|
return () => set(null);
|
||||||
)
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const value = derived(current, ($current, set: (value: T | null) => void) => set(get($current.value)), null)
|
const error = derived(
|
||||||
const error = derived(current, ($current, set: (error: E | null) => void) => set(get($current.error)), null)
|
promise,
|
||||||
|
($promise, set: (error: E | null) => void) => {
|
||||||
|
$promise.catch((error: E) => set(error));
|
||||||
|
return () => set(null);
|
||||||
|
},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const pending = derived(current, (_, set) => set(false), true)
|
const pending = readable(true, (set: (value: boolean) => void) => {
|
||||||
const success = derived(current, ($current, set: (success: boolean) => void) => set(get($current.success)), false)
|
initial.finally(() => set(false));
|
||||||
const loading = derived(current, ($current, set: (pending: boolean) => void) => set(get($current.pending)), true)
|
});
|
||||||
|
|
||||||
return { value, error, pending, success, loading }
|
const loading = derived(
|
||||||
|
[value, error],
|
||||||
|
(_, set) => {
|
||||||
|
set(false);
|
||||||
|
return () => set(true);
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
const success = derived(
|
||||||
|
[value],
|
||||||
|
(_, set) => {
|
||||||
|
set(true);
|
||||||
|
return () => set(false);
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
return { value, error, pending, loading, success };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useAsyncRefresh
|
export default useAsyncRefresh;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"module": "es6",
|
"module": "es6",
|
||||||
"lib": ["es2017", "es2019.array", "dom", "dom.iterable"],
|
"lib": ["es2017", "es2019.array", "es2018.promise", "dom", "dom.iterable"],
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"anki/*": ["../bazel-bin/ts/lib/*"]
|
"anki/*": ["../bazel-bin/ts/lib/*"]
|
||||||
|
|
Loading…
Reference in a new issue