【问题标题】:Handle Multiple Calls Correctly in Javascript在 Javascript 中正确处理多个调用
【发布时间】:2019-11-26 04:47:32
【问题描述】:

以下是我的场景,其中我使用搜索关键字访问搜索 API,但由于时间不均,它占用的 UI 没有正确更新。

场景-

  1. 我在输入框中输入a,搜索请求就像-search/?q=a 解决问题的时间是5sec
  2. 我继续输入,现在查询字符串类似于 - ab,所以另一个查询类似于 - search/?q=ab 并假设它需要 4sec 的时间才能得到解决。
  3. 我继续输入,现在查询字符串是 abc,所以另一个查询类似于 - search/?q=abc 并假设解决它需要时间是 3sec

所以在这里你可以看到 - 请求 1 在 5 秒内获取数据,2 在 4 秒内获取数据,在 3 秒内获取数据,所以在 UI 中结果类似于 -

a => /?q=a (5s)
ab => /?q=ab (4s)
abc => /?q=abc (3s)

UI 中的结果 -

=> Result of abc
=> Result of abb
=> Result of a

但正确的顺序应该是——

=> Result of a
=> Result of ab
=> Result of abc

我的尝试 -

  1. 我试过Promise.all。问题是它只会在 12 秒(5+4+3 秒)后更新 UI。
  2. 我试过Promise.allSettled(),但问题是我存储承诺的数组是动态的,所以我不确定这是否可以增强。

我相信这不是极端情况,人们可能已经面对它。让我知道我还能尝试什么。

仅供参考 - 我还阅读了有关 AbortController 的信息,但明确提到它是一种实验性技术,所以我在使用它时有点犹豫。

【问题讨论】:

  • 一种简单的方法是让您的搜索按您想要的任何顺序进行,但在搜索响应中包含搜索请求,并且只显示与当前值匹配的响应。在您的场景中,a 和 ab 搜索的结果将被简单地忽略。其他线索是延迟搜索,以便在用户输入时取消无用的调用(使用 debounce,与 promise 具有相同的支持)。
  • 如果你要找的是订单,你要Promise.eachasync/await
  • 通常您会保留对上次发出的请求的引用。当新的搜索出现时,取消现有请求,因为您不再需要该响应。然后发出下一个请求。另见stackoverflow.com/a/37492399/1260204

标签: javascript reactjs ecmascript-6 promise fetch


【解决方案1】:

在客户端有几种方法可以做到这一点。我知道的最常见的方法是使用 debounce(来自 lodash)

  • 使用去抖动,https://lodash.com/docs/4.17.15

    const loadData = (query) => {...}
    const debouncedLoadData = debounce(loadData, 200);
    
  • 使用 setTimeout 和 clearTimeout。

有些人提出了对种族的担忧,这是真的。为了使它完美,我们需要实现请求的取消。到目前为止,我可以推荐使用具有建筑取消功能的 axios,https://github.com/axios/axios#cancellation

【讨论】:

  • 如果用户在 2 个输入之间等待超过 200 毫秒且少于 1000 毫秒(5s - 4s)怎么办?
  • debounce 是一个很好的优化,但它不会阻止竞争条件。
  • 只需找到一个适合您的情况的号码 :)。为了防止竞争条件,我们当然需要实现一个取消承诺的解决方案:)
  • @Piou 好点,我认为使用 axios 和取消将确保解决问题
【解决方案2】:

在反应中你可以使用钩子,请看this工作示例

【讨论】:

    猜你喜欢
    • 2014-02-08
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    相关资源
    最近更新 更多