【问题标题】:Poll API until a path in the response object is Successful | Failure - Typescript轮询 API,直到响应对象中的路径成功 |失败 - 打字稿
【发布时间】:2021-01-13 00:51:24
【问题描述】:

我有一个函数,它接受一个字符串和一个路径值,并检查结果中的路径是返回 1 还是返回 -1。我用多个请求触发了这个函数,除了一个请求之外,一切似乎都成功了。例如,如果我用 10 个不同的 URL 连续调用函数(一个接一个,而不是在一个数组中),则 promise 被解析为 9 而不是第 10 个。

这是我的代码:

enum Status {
  Queued = 0,
  Started = 1,
  Finished = 2,
  Failed = -1,
}

let dataFetchingTimer: number;

export const getDataAtIntervals = (url: string, path: string): Promise<any> => {
  clearTimeout(dataFetchingTimer);
  return new Promise<any>((resolve: Function, reject: Function): void => {
    try {
      (async function loop() {
        const result = await API.load(url);
        console.log(`${url} - ${JSON.stringify(result)}`)
        if (
          get(result, path) &&
          (get(result, path) === Status.Finished ||
            get(result, path) === Status.Failed)
        ) {
          return resolve(result); // Resolve with the data
        }
        dataFetchingTimer = window.setTimeout(loop, 2500);
      })();
    } catch (e) {
      reject(e);
    }
  });
};

export const clearGetDataAtIntervals = () => clearTimeout(dataFetchingTimer);

请指教。在上图中,4535 只被调用了一次。并且在返回 2 或 -1 之前不会被调用。

【问题讨论】:

  • 不能运行就不好说,但我猜这与共享相同dataFetchingTimer变量的所有请求有关。目前尚不清楚您如何称呼它,或者您的输出对应于什么
  • 我称之为 const result = await getDataAtIntervals(url, “status”)。 Setstate(oldState=> {return {data: {...oldState.data, result}}})
  • 我可以创建多个 settimeout 吗?
  • 我想是的。我不习惯 Typescript,所以我使用了 JS,但这可能会让你想到一些可能的事情:jsfiddle.net/gx3t8d0e
  • @blex 谢谢。将尝试并让您知道

标签: javascript typescript promise async-await settimeout


【解决方案1】:

对所有调用使用单一超时可能会导致奇怪的行为。避免调用之间冲突的解决方案可能是每次调用都使用超时。你可以按照这些思路做一些事情(我使用简单的 JS,因为我不习惯 Typescript)

const Status = {
  Queued: 0,
  Started: 1,
  Finished: 2,
  Failed: -1,
}

let dataFetchingTimerMap = {
  // Will contain data like this:
  // "uploads/4541_status": 36,
};

const setDataFetchingTimer = (key, cb, delay) => {
  // Save the timeout with a key
  dataFetchingTimerMap[key] = window.setTimeout(() => {
    clearDataFetchingTimer(key); // Delete key when it executes
    cb(); // Execute the callback
  }, delay);
}

const clearDataFetchingTimer = (key) => {
  // Clear the timeout
  clearTimeout(dataFetchingTimerMap[key]);
  // Delete the key
  delete dataFetchingTimerMap[key];
}

const getDataAtIntervals = (url, path) => {
  // Create a key for the timeout
  const timerKey = `${url}_${path}`;
  // Clear it making sure you're only clearing this one (by key)
  clearDataFetchingTimer(timerKey);

  return new Promise((resolve, reject) => {
    // A try/catch is useless here (https://jsfiddle.net/4wpezauc/)
    (async function loop() {
      // It should be here (https://jsfiddle.net/4wpezauc/2/)
      try {
        const result = await API.load(url);
        console.log(`${url} - ${JSON.stringify(result)}`);
        if ([Status.Finished, Status.Failed].includes(get(result, path))) {
          return resolve(result); // Resolve with the data
        }
        // Create your timeout and save it with its key
        setDataFetchingTimer(timerKey, loop, 2500);
      } catch (e) {
        reject(e);
      }
    })();
  });
};

const clearGetDataAtIntervals = () => {
  // Clear every timeout
  Object.keys(dataFetchingTimerMap).forEach(clearDataFetchingTimer);
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 2023-03-07
    • 1970-01-01
    • 2019-09-07
    • 2021-04-21
    • 1970-01-01
    相关资源
    最近更新 更多