更好地理解 API 请求的 debounceTime (RXJS)

Better understand debounceTime (RXJS) for an API request

我正在尝试创建一个搜索引擎(输入),每次用户开始输入时,它都会在发送查询调用之前稍等片刻。据我了解,我们将导入

import { of } from "rxjs";
import { debounceTime } from "rxjs/operators";

使用of的目的是因为我们将使用字符串。至于 debounceTime,我们只想处理(发出请求)到在我们选择的设定时间内写入的最后一个输入。对于这个实现,我设置的方式是

const PostTypeSelection = ({ client }) => {
  const [search, updateSearch] = useState("");
  const [tags, updateTags] = useState([]);
  const searchObserver = of(search);

  const handleChange = e => {
    const { value } = e.target;
    updateSearch(value);
    searchObserver
      .pipe(
        debounceTime(1000),
        distinctUntilChanged()
      )
      .subscribe(x => console.log("we run query here", x));
  }

  return (
    <div>
      <p>Select tags you'll want to see</p>
      <input
        type="text"
        name="search"
        placeholder="Type tag name"
        onChange={handleChange}
      />
      {tags.map(tag => {
        return (
          <div key={tag.id}>
            {tag.name} ({tag.count})
          </div>
        );
      })}
    </div>
  );
};

我的主要问题是我的实现有什么问题?当我开始输入并且 console.log 立即得到 运行 时没有延迟。我注意到的另一个问题是,如果我尝试使用 delay,它不会删除以前的请求,只是在设定的时间后发送它们。

感谢所有帮助,尤其是在更好地理解如何使用 Observer 和更好地理解 debounceTime

的正确用法方面

请对我要说的话持保留态度。我不是 Rxjs 开发人员(老实说我从未使用过 lib )但我明白了这些概念。

我发现你的实现有两个问题:

  1. 对于您正在创建的每个按键以及新的观察者和订阅它,因为所有管道和订阅代码都在处理程序中。
  2. 根据文档中关于 of 的内容,它按顺序发出提供的值。例如:of(1,2,3,3)。在这里,我认为您没有序列。每次更新状态时,整个函数都会运行,导致 of begin 用每个值调用一次:of('a')of('ab')of('abc'),而不是 of('a', 'ab', 'abc')

这就是我为让它发挥作用所做的工作:

const PostTypeSelection = ({ client }) => {
  const [tags, updateTags] = useState([]);
  const searchObserver = new Subject().pipe(
    debounceTime(1000),
    distinctUntilChanged()
  );
  searchObserver.subscribe(x => console.log("we run query here", x))
  const handleChange = e => {
    const { value } = e.target;
    searchObserver.next(value)
  }

  return (
    <div>
      <p>Select tags you'll want to see</p>
      <input
        type="text"
        name="search"
        placeholder="Type tag name"
        onChange={handleChange}
      />
      {tags.map(tag => {
        return (
          <div key={tag.id}>
            {tag.name} ({tag.count})
          </div>
        );
      })}
    </div>
  );
};