Создание 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$(), чтобы обновление происходило с задержкой в одну секунду.

Edit Tutorial