再次调用onSearch时取消之前的promise.all

Cancel previous promise.all when onSearch is called again

我有一个反应组件,它有一个自动完成功能,当用户输入超过 3 个字符时调用 onSearch。

一旦发生这种情况,就会调用 Util 文件 (Requests.js) 中的一个函数,并且 returns 一个 axios promise,其中包含从这 3 个字符中搜索到的数据。

有时我需要根据过滤需要多次调用这个函数,所以我循环了很多次我需要并创建一个 axios promises 数组。

然后我promise.all它并在自动完成中显示结果。

我的问题是,如果用户输入 "tes",进程启动可能需要一段时间才能完成,具体取决于他们的搜索词(这很好)。如果他们随后键入添加 "t"(在去抖 window 之后)并使搜索词 "test" 另一个进程启动但它是同步的并等待 "tes" 进程完成之前开始、结束和展示。

很明显第一次调用onSearch需要启动,但是如果后续调用onSearch怎么取消之前的Promise.all?

这是 Observable Streams 的主要用例,但为了保持简单,这里有一个想法。

每当您进行搜索时,增加一个计数器并保存开始搜索时计数器的值。搜索完成后,检查计数器是否改变;如果是,则该搜索不再有效。

React 中的(未测试)示例(因为您的问题被这样标记):

class MyComponent extends React.Component {
  state = { items: [] }

  searchCounter = 1

  constructor() {
    super(...arguments)
    this.debouncedSearch = debounce(this.search.bind(this), 500)
  }

  search(e) {
    const countBefore = ++this.searchCounter
    return axios.get('<url>', { params: { term: e.target.value} }).then(r => {
      // Another search happened before the response was done; cancel.
      if (countBefore !== this.searchCounter) {
        return
      }
      this.setState({ items: r.data })
    })
  }

  render() {
    return (
      <div>
        <input type="text" onKeyUp={this.debouncedSearch.bind(this)} />
        <ul>
          {this.state.items.map(item => (
            <li key={item.key}>{item.value}</li>
          ))}
        </ul>
      </div>
    )
  }
}