【问题标题】:What is a good way to delay api call?什么是延迟api调用的好方法?
【发布时间】:2021-03-27 23:55:25
【问题描述】:

在我的应用程序(React + Redux + axios + redux-thunk + Typescript)中,当我进行 API 调用、更改数据库中的项目并在表中显示当前、更改的状态时,我遇到了这种情况。所以,它看起来像:

const changeItem = () => changeItemState(item.id).then(getItem(item.id));

两个动作(changeItemStategetItem)都是从 reducer 文件中导入的。问题是,在后端站点上更改项目流程需要太长时间。所以,我重新加载表(调用 api 获取项目 - getItem(item.id))但后端更改过程仍在进行中,所以我收到旧状态。 100-300 毫秒后,我可以再次查询项目(例如刷新页面)并获取项目的新状态。但我不想手动进行。我想后端准备好我的项目以显示新状态后重新加载表格。

问题是 - 如何延迟获取项目操作?这有什么前端模式吗?我想避免使用这样的“setTimeout()”方法(imo 这不是一个理想的解决方案):

const changeItem = () => changeItemState(item.id).then(setTimeout(function(){ getItem(item.id); }, 300));,

【问题讨论】:

  • 这似乎完全取决于您的后端能够做什么,它是否能够以某种方式通知异步任务已完成?我会说这更像是一个后端问题。在前端,我唯一能看到的是您使用setTimeout 所做的解决方法
  • 您可以 1. 更改项目状态块,直到后端更新所有内容或 2. 以小增量轮询(设置间隔),仅在收到新数据时更新本地 JS 状态。
  • 这里的 setTimeout 语法是非常错误的;它不会在此处的then 操作中触发,而是立即触发。 (事实上​​,第一个例子同样是错误的。)

标签: javascript reactjs asynchronous redux axios


【解决方案1】:

你可以像这样承诺setTimeout

const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

那么,

const changeItem = () =>
  changeItemState(item.id)
    .then(() => delay(300))
    .then(() => getItem(item.id));

或等效地使用异步函数

const changeItem = async () => {
  await changeItemState(item.id);
  await delay(item.id);
  return getItem(item.id);
}

【讨论】:

    【解决方案2】:

    好吧,如果你不使用 Websocket,就没有优雅的解决方案 (https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)

    唯一的方法是让setTimeout 延迟并将旧数据与新数据进行比较。这是你能做的最好的。

    但是,如果您使用 Websockets 路由,您可以与 BE 进行实时通信,它会发出更改,您的应用会对这些更改做出反应。

    这将要求您对 BE 进行重构以支持 Websocket。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      • 2013-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多