轮询 API 直到响应对象中的路径成功 |失败 - 打字稿 [英] Poll API until a path in the response object is Successful | Failure - Typescript

查看:21
本文介绍了轮询 API 直到响应对象中的路径成功 |失败 - 打字稿的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是我的代码:

枚举状态{排队 = 0,开始 = 1,完成 = 2,失败 = -1,}让 dataFetchingTimer:数字;export const getDataAtIntervals = (url: string, path: string): Promise

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

解决方案

对所有调用使用单个超时可能会导致出现奇怪的行为.避免调用之间发生冲突的解决方案可能是对每个调用使用超时.你可以按照这些方式做一些事情(我使用了简单的 JS,因为我不习惯打字稿):

const 状态 = {排队:0,开始:1,完成:2,失败:-1,}让 dataFetchingTimerMap = {//将包含这样的数据://上传/4541_状态":36,};const setDataFetchingTimer = (key, cb, delay) =>{//用key保存超时时间dataFetchingTimerMap[key] = window.setTimeout(() => {clearDataFetchingTimer(key);//执行时删除keycb();//执行回调}, 延迟);}const clearDataFetchingTimer = (key) =>{//清除超时clearTimeout(dataFetchingTimerMap[key]);//删除密钥删除 dataFetchingTimerMap[key];}const getDataAtIntervals = (url, path) =>{//创建超时键const timerKey = `${url}_${path}`;//清除它确保你只清除这个(按键)clearDataFetchingTimer(timerKey);返回新的承诺((解决,拒绝)=> {//这里的 try/catch 是无用的 (https://jsfiddle.net/4wpezauc/)(异步函数循环(){//它应该在这里 (https://jsfiddle.net/4wpezauc/2/)尝试 {const result = await API.load(url);console.log(`${url} - ${JSON.stringify(result)}`);if ([Status.Finished, Status.Failed].includes(get(result, path))) {返回解决(结果);//用数据解析}//创建你的超时并用它的键保存它setDataFetchingTimer(timerKey, loop, 2500);}赶上(e){拒绝(e);}})();});};const clearGetDataAtIntervals = () =>{//清除每次超时Object.keys(dataFetchingTimerMap).forEach(clearDataFetchingTimer);};

I have a function which accepts a string and a path value and checks whether the path at the result returns a 1 or a -1. I fire the function with multiple requests and everything seems to be successful except for one. For example, if I call the function with 10 different URL's continously (one by one, not in an array), the promise is resolved for 9 but not for the 10th one.

This is my code:

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);

Please advice. In the above image, 4535 is called only once. and is not called until 2 or -1 is returned.

解决方案

Using a single timeout for all your calls might be the cause of weird behaviors. A solution to avoid collisions between your calls might be to use a timeout per call. You could do something along these lines (I used simple JS because I'm not used to 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);
};

这篇关于轮询 API 直到响应对象中的路径成功 |失败 - 打字稿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆