【问题标题】:Cancel previous promise.all when onSearch is called again再次调用 onSearch 时取消之前的 promise.all
【发布时间】:2023-04-01 13:54:01
【问题描述】:

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

一旦发生这种情况,将调用 Util 文件 (Requests.js) 中的函数并返回 axios 承诺,其中包含从这 3 个字符中搜索到的数据。

有时我需要根据过滤需要多次调用此函数,因此我需要循环多次并创建 axios 承诺数组。

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

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

显然第一次调用 onSearch 时它需要启动,但是如果调用任何后续的 onSearches 我如何取消之前的 Promise.all?

【问题讨论】:

    标签: reactjs axios es6-promise


    【解决方案1】:

    这是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>
        )
      }
    }
    

    【讨论】:

    • 这行得通,所以结果不会双倍返回,这很好。它不会停止最初的承诺。我认为现在一切都很好。猜猜我需要学习 Observable 流!
    • 您需要Promise.all 做什么? :)
    • 因为返回的是一个 axios promises 数组,我 promise.all 从中获取所有数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多