javascript 如何向API发出请求直到得到预期的结果

aiqt4smr  于 2023-01-04  发布在  Java
关注(0)|答案(2)|浏览(166)

有一个带有json的URL。有时候检索到的数据没有我想要的数据,那么我想请求它四次以上,直到我得到正确的结果。我怎么能用正确的方法做到这一点呢?当我调用这个函数时,返回速度非常快...它感觉它不是发出5个请求,而是只有一个。
我正在调用TryToUpdate函数。

const getText = new Promise((resolve, reject) => {
  var retorno;
  fetch('URL').then(i => i.json()).then(i => {
    retorno = i ? .result[0] ? .edited_channel_post ? .text;
    if (retorno.includes('Texto:')) {
      resolve({
        data: retorno,
      });
    } else {
      reject('unavailable');
    }
  })
})

async function tryToUpdate(tries = 0) {
  var retorno;
  var tryNum = tries
  if (tries >= 5) {
    console.log('Cant update.');
    return undefined;
  } else {
    getText
      .then(i => retorno)
      .catch(() => {
        console.log('Cannot reach result. Try num:' + tryNum);
        tryToUpdate(tryNum + 1);

      });
  }
}

我试着向一个URL发出5个请求,直到得到预期的结果。

7eumitmz

7eumitmz1#

根据我的理解,这个问题是一个UX问题,也就是说,它发生得太快了。如果有问题,你可以等待一段时间,比如:

setTimeout(function() {
    tryToUpdate(tryNum+1);
}, 200);
wfauudbj

wfauudbj2#

这可以看作是一个有条件构建的承诺链,下面的函数tryToUpdate捕获错误、暂停和递归多达5次。

// generic pause code
const pause = async (ms) => new Promise(res => setTimeout(res, ms));

// this is the OP's fetch rewritten to demo.  see note below the snippet
function getText(invocation) {
  // pause 100ms, fail on the first few, then succeed
  return pause(100).then(() => {
    if (invocation < 3) throw 'failure';
    return Promise.resolve('success')
  })
}

function tryToUpdate(invocation=0) {
  return getText(invocation).catch(error => {
    if (invocation < 5) {
      console.log('failed, retrying')
      // the OP should select an appropriate pause.
      // no pause might be too fast for the api
      return pause(1000).then(() => tryToUpdate(invocation+1))
    } else {
      console.log('failed, and no more retry')
      throw error
    }
  })
}

tryToUpdate().then(console.log)

OP的获取可以通过不创建新的Promise来改进...

const getText = url => {
  return fetch('URL').then(i => i.json()).then(i => {
    retorno = i?.result[0]?.edited_channel_post?.text;
    return retorno.includes('Texto:') ? { data: retorno } : throw 'unavailable';
  })
}

相关问题