Как попробовать JS fetch () метод в цикле - PullRequest
1 голос
/ 19 февраля 2020

У меня есть следующая JS функция

func() {
  return fetch({
    ...
  }).then({
    ...
  })catch({
    ...
  })
}

В ней я возвращаю обещание, возвращенное fetch(). В случае неудачи (ie вызывает catch() блок) я хочу повторить все это. Что-то вроде всего этого в while (true) l oop, но я не могу понять, как сделать это с обещаниями.

Есть предложения?

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Вы должны внимательно посмотреть на обещания и асин c await.

async function fetchUntilSucceeded() {
  let success = false;
  while(!success) {
    try {
      let result = await fetch(...);
      success = true;
      //do your stuff with your result here
    } catch {
      //do your catch stuff here
    }
  }
}

Если вам просто нужны результаты:

async function fetchUntilSucceeded() {
  while(true) {
    try {
      return await fetch(...);
    } 
  }
}

Но будьте осторожны с таким кодом, как это может никогда не решить! также он может отправлять много запросов без ожидания между ними.

0 голосов
/ 19 февраля 2020

Вы можете просто написать al oop и отсчитывать попытки до тех пор, пока одна из них не удастся или вы не закончите. async / await делает это легко. Ниже приведен минимальный полный пример.

Обратите внимание, что API выборки использует флаг response.ok, чтобы гарантировать, что статус ответа попадает в диапазон 200. Упаковка с try / catch достаточна только для покрытия сбоев соединения. Если ответ указывает на неверный запрос, повторная попытка, скорее всего, неуместна. Этот код разрешает обещание в таких случаях, но вы можете рассматривать !response.ok как ошибку и повторить попытку, если вы будете sh.

const fetchWithRetry = async (url, opts, tries=2) => {
  const errs = [];
  
  for (let i = 0; i < tries; i++) {
    console.log(`trying GET '${url}' [${i + 1} of ${tries}]`); // for illustration
    
    try {
      return await fetch(url, opts);
    }
    catch (err) {
      errs.push(err);
    }
  }
  
  throw errs;
};

fetchWithRetry("https://httpstat.us/400")
  .then(response => console.log("response is OK? " + response.ok))
  .catch(err => console.error(err));

fetchWithRetry("foo")
  .catch(err => console.error(err.map(e => e.toString())));

fetchWithRetry("https://httpstat.us/200")
  .then(response => response.text())
  .then(data => console.log(data))
  .catch(err => console.error(err));
...