使用 $ 创建 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$()
调用中,以便它延迟一秒更新。