使用 $ 创建 API

优化器的一个强大功能是,您可以使用 $ 后缀创建自己的 API。

假设我们想要一个延迟方法,它可以延迟加载回调。通常我们需要编写类似这样的代码:

setTimeout(() => {
  // I am eagerly loaded, but it would be better if I was lazy-loaded.
  ...
}, timeout);

上面示例的问题是,回调必须提前下载和创建。如果闭包很大或回调从未执行(或只在稍后执行),这可能是一个问题。

更好的解决方案是使用 delay$ 方法,它可以延迟加载与回调相关的闭包。类似这样:

delay$(() => {
  // I am lazy-loaded only when I need to be executed.
  ...
}, 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$() 调用中,以便它延迟一秒更新。

编辑教程