如何创建延迟底层信号并立即清除的信号
How to create a signal that delays the underlying signal and clears immediately
我想制作一个信号,在一定延迟后将其自身设置为底层信号或备忘录,并在底层信号被清除后立即清除。下面的代码演示了我想要的。
import { render } from "solid-js/web";
import { For, createSignal, createEffect } from "solid-js";
function Counter() {
const [s, setS] = createSignal(undefined)
const [delayedS, delayedSetS] = createSignal(undefined)
setTimeout(() => {
setS(10)
}, 1000)
setTimeout(() => {
setS(undefined)
}, 3000)
createEffect(() => {
let res = s()
if (res !== undefined) {
setTimeout(() => delayedSetS(res), 1000)
} else {
delayedSetS(undefined)
}
})
return (<>
<span> S {s()} </span>
<span> Delayed S {delayedS()}</span>
</>)
}
render(() => <Counter />, document.getElementById("app"));
这可行,但这是一种正确的方法吗?我不确定 createDeferred 是否提供此功能,但我不想使用它,因为它使用调度程序我不确定它的作用。
您的尝试完全有效。
createDeferred
,虽然它看起来像是有类似的用例,但它不会按预期在这里工作,因为:
- 传递给
createDeferred
的超时时间不是在导致更新之前等待的准确时间量 – 它是浏览器空闲之前等待的最大超时时间。
- 在将信号更新为
undefined
和其他值之前会发生超时。
const delayedS = createDeferred(s)
设置信号的首选原语是createComputed
。这是一个纯粹的计算——类似于 createMemo
——这意味着它会在效果之前立即 运行。在简单示例中,效果的使用通常没有区别,但使用效果设置信号可能会导致不必要的更新。
createComputed(
on(s, (v) => {
if (v) setTimeout(() => setDelayedS(v), 1000);
else setDelayedS();
})
);
另外清除设置上的超时 undefined
没有延迟发生,可以消除一些计时故障。
let timeoutId = 0;
createComputed(
on(s, (v) => {
if (v) timeoutId = setTimeout(() => setDelayedS(v), 1000);
else {
setDelayedS();
clearTimeout(timeoutId);
}
})
);
onCleanup(() => clearTimeout(timeoutId));
我想制作一个信号,在一定延迟后将其自身设置为底层信号或备忘录,并在底层信号被清除后立即清除。下面的代码演示了我想要的。
import { render } from "solid-js/web";
import { For, createSignal, createEffect } from "solid-js";
function Counter() {
const [s, setS] = createSignal(undefined)
const [delayedS, delayedSetS] = createSignal(undefined)
setTimeout(() => {
setS(10)
}, 1000)
setTimeout(() => {
setS(undefined)
}, 3000)
createEffect(() => {
let res = s()
if (res !== undefined) {
setTimeout(() => delayedSetS(res), 1000)
} else {
delayedSetS(undefined)
}
})
return (<>
<span> S {s()} </span>
<span> Delayed S {delayedS()}</span>
</>)
}
render(() => <Counter />, document.getElementById("app"));
这可行,但这是一种正确的方法吗?我不确定 createDeferred 是否提供此功能,但我不想使用它,因为它使用调度程序我不确定它的作用。
您的尝试完全有效。
createDeferred
,虽然它看起来像是有类似的用例,但它不会按预期在这里工作,因为:
- 传递给
createDeferred
的超时时间不是在导致更新之前等待的准确时间量 – 它是浏览器空闲之前等待的最大超时时间。 - 在将信号更新为
undefined
和其他值之前会发生超时。
const delayedS = createDeferred(s)
设置信号的首选原语是createComputed
。这是一个纯粹的计算——类似于 createMemo
——这意味着它会在效果之前立即 运行。在简单示例中,效果的使用通常没有区别,但使用效果设置信号可能会导致不必要的更新。
createComputed(
on(s, (v) => {
if (v) setTimeout(() => setDelayedS(v), 1000);
else setDelayedS();
})
);
另外清除设置上的超时 undefined
没有延迟发生,可以消除一些计时故障。
let timeoutId = 0;
createComputed(
on(s, (v) => {
if (v) timeoutId = setTimeout(() => setDelayedS(v), 1000);
else {
setDelayedS();
clearTimeout(timeoutId);
}
})
);
onCleanup(() => clearTimeout(timeoutId));