Создание API с $
Мощной особенностью оптимизатора является то, что вы можете создавать свои собственные API с суффиксом $
.
Представьте, что мы хотим иметь метод задержки, который лениво загружает свою функцию обратного вызова. Обычно мы пишем что-то вроде этого:
setTimeout(() => {
// Я загружаюсь сразу, но было бы лучше, если бы я загружался лениво.
...
}, timeout);
Проблема с приведённым выше примером заключается в том, что обратный вызов должен быть загружен и создан безотлагательно. Это может быть проблемой, если замыкание имеет большой размер или если обратный вызов никогда не выполняется (или выполняется, но позже).
Лучшим решением было бы иметь метод delay$
, который может лениво загружать замыкание, связанное с обратным вызовом. Что-то вроде этого:
delay$(() => {
// Я лениво загружаюсь только тогда, когда нужно выполниться.
...
}, 1000)
В приведённом выше решении обратный вызов загружается только тогда, когда delay$
готов его выполнить.
Создание своего API с суффикосм $
Среда выполнения Qwik работает с QRL
. Для этого мы определяем метод следующим образом:
export function delayQrl<T>(fn: QRL<() => T>, delayInMs: number): Promise<T> {
return new Promise((res) => {
setTimeout(() => {
res(fn.invoke());
}, delayInMs);
});
}
Этот метод умеет принимать QRL
и выполнять его после определённой задержки. Ключевым моментом здесь является то, что метод QRL.invoke()
вызывается, когда задержка готова, и поэтому является ленивым.
Следующим шагом будет преобразование метода delayQrl
в псевдоним delay$
. Это делается с помощью implicit$FirstArg
таким образом:
export const delay$ = implicit$FirstArg(delayQrl);
Вот типы, чтобы было понятнее, что происходит.
declare function delayQrl<T>(fn: QRL<() => T>, delayInMs: number): Promise<T>;
declare function delay$<T>(fn: () => T, delayInMs: number): Promise<T>;
Вышеприведённое позволяет нам использовать delay$
во вложенном виде, но оптимизатор преобразует delay$
в форму delayQrl
.
ПРИМЕЧАНИЕ Два метода должны иметь одинаковый префикс. Итак, общая форма такова:
export const SOME_NAME_Qrl = ...;
export const SOME_NAME_$ = implicit$FirstArg(SOME_NAME_Qrl);
Пример
В нашем примере мы выполняем store.count++
и store.delay++
одновременно. Оберните вызов store.delay
в вызов delay$()
, чтобы обновление происходило с задержкой в одну секунду.