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