如何创建一个延迟基础信号并立即清除的信号

发布于 2025-01-26 22:43:44 字数 892 浏览 4 评论 0原文

我想制作一个信号,该信号在一定的延迟后设置为基础信号或备忘录,并立即清除基础信号。以下代码演示了我想要的。

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是否提供此功能,尽管我不想使用它,因为它使用了调度程序,我不确定它的作用。

I want to make a signal that sets itself to underlying signal or a memo after a certain delay, and clears immediately if the underlying signal is cleared. The following code demonstrates what I want.

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"));

This works, though Is this a correct approach. I am not sure if createDeferred provides this functionality, though I don't want to use that, since it uses a scheduler I am not sure what it does.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无言温柔 2025-02-02 22:43:44

您的尝试是完全有效的。

create> create eferred类似的用户酶,它在这里无法按预期工作,因为:

  1. 超时传递给createferred不是它在引起更新之前等待的确切时间 - 这是等待之前的最大超时时间浏览器变得空闲。
  2. 超时会在将信号更新为不确定的和其他值之前发生。
const delayedS = createDeferred(s)

设置信号的优选原始性是 creation creationecompated 。它是一个纯粹的计算 - 类似于createMeMo - 这意味着它将在效果之前立即运行。在简单的示例中,通常没有效果的差异,但是使用效果来设置信号可能会导致更多的更新。

  createComputed(
    on(s, (v) => {
      if (v) setTimeout(() => setDelayedS(v), 1000);
      else setDelayedS();
    })
  );

另外,将集合的超时清除到不确定的时,这种不延迟会消除某些正时故障。

  let timeoutId = 0;
  createComputed(
    on(s, (v) => {
      if (v) timeoutId = setTimeout(() => setDelayedS(v), 1000);
      else {
        setDelayedS();
        clearTimeout(timeoutId);
      }
    })
  );
  onCleanup(() => clearTimeout(timeoutId));

Your attempt was totally valid.

The createDeferred, although it seams like it has a similar usecase, it wouldn't work here as intended, because:

  1. The timeout passed to createDeferred is not an exact amount of time that it will wait before causing updates – it is a maximum timeout to wait before browser becomes idle.
  2. The timeout would happen before both updating the signal to undefined and other values.
const delayedS = createDeferred(s)

A preferable primitive for setting signals is createComputed. It is a pure computation – similar to createMemo – meaning that it will run immediately before effects. In simple examples there is usually no difference to use of effect, but using an effect for setting signals could potentially cause more updates than necessary.

  createComputed(
    on(s, (v) => {
      if (v) setTimeout(() => setDelayedS(v), 1000);
      else setDelayedS();
    })
  );

Additionally clearing the timeout on the set to undefined that happens without a delay, could eliminate some timing glitches.

  let timeoutId = 0;
  createComputed(
    on(s, (v) => {
      if (v) timeoutId = setTimeout(() => setDelayedS(v), 1000);
      else {
        setDelayedS();
        clearTimeout(timeoutId);
      }
    })
  );
  onCleanup(() => clearTimeout(timeoutId));
最终幸福 2025-02-02 22:43:44

您可以使用 @solid-primitives/stolid-primitives/stolice>一些延迟的反应性功能。

import {createMemo, createSignal} from 'solid-js';
import {createScheduled, throttle} from '@solid-primitives/scheduled';

const [count, setCount] = createSignal(0);
const scheduled = createScheduled(callback => throttle(callback, 1000)); // 1000 ms delay

const debouncedCount = createMemo(
  (previousCount) => scheduled() ? count() : previousCount,
  0
);

createEffect(() => {
  // This message gets printed at most once every second because debouncedCount()
  // is a dependency, regardless of how many times setCount is called.
  console.log(debouncedCount());
});

在这里,如果要重复调用setCountdebouncedcount只会每秒更新。还有其他调度选项,例如debounce,以及领导之类的修饰符。

上面的页面还具有a demo ,这些证明了不同的调度选项之间的差异。

You can use the @solid-primitives/scheduled package which has some delayed reactive functionality.

import {createMemo, createSignal} from 'solid-js';
import {createScheduled, throttle} from '@solid-primitives/scheduled';

const [count, setCount] = createSignal(0);
const scheduled = createScheduled(callback => throttle(callback, 1000)); // 1000 ms delay

const debouncedCount = createMemo(
  (previousCount) => scheduled() ? count() : previousCount,
  0
);

createEffect(() => {
  // This message gets printed at most once every second because debouncedCount()
  // is a dependency, regardless of how many times setCount is called.
  console.log(debouncedCount());
});

Here, if one were to call setCount repeatedly, debouncedCount will only update every second. There are other scheduling options such as debounce, and modifiers such as leading.

The page above also has a demo that demonstrates the differences between the different scheduling options.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文