如何在for循环中的具有精确索引的元素上重复迭代?

时间:2019-06-27 18:51:16

标签: javascript arrays loops for-loop

我有一个带有URL的数组,我必须遍历它才能下载HTML文件。如果某个URL无法加载(例如由于连接问题),则该HTML文件将不会下载,因为循环将转到下一个迭代。我的目标是,如果发生错误,程序应将当前迭代重复3次,然后转到下一个迭代。

这是我想要实现的目标:

let filteredUrls = [ 'url1', 'url2', 'url3'];
for (let id in filteredUrls) {
  let currentUrl = filteredUrls[id];
    try {
      //open currentUrl, do some stuff...
    } catch (error) {
      //if there's an error, repeat the current loop 3 times, 
      //after that, move to the next iteration
    }
}

我该怎么做?有办法吗?

2 个答案:

答案 0 :(得分:1)

如果您的下载代码是异步的,那么您可能要使用递归函数,而不是仅仅再次重复循环。

let filteredUrls = [ 'url1', 'url2', 'url3'];
for (let id in filteredUrls) {
  let currentUrl = filteredUrls[id];
  downloadFile( currentUrl, 0 );
}

function downloadFile( url, tryCount ) {
  try {
    //open currentUrl, do some stuff...
  } catch (error) {
    tryCount++;
    if ( tryCount < 3 ) {
      downloadFile( url, tryCount );
    }
  }
}

答案 1 :(得分:1)

您还没有显示如何获取页面内容,但是我假设您使用的是类似fetchXMLHttpRequest的东西。如果您使用的是提取,它会返回一个Promise,该承诺会因网络错误而拒绝,这意味着您可以将回调附加到其.catch()方法上,以重试提取。如果您使用的是XMLHttpRequest,则它有一个onerror事件,您可以附加相同的重试回调。

我建议您将内容获取代码分解为一个接受URL和重试编号的函数,然后返回XMLHttpRequest或fetch Promise。这样,您可以使错误回调仅再次调用相同的函数,但是为重试参数传递了retries-1

示例:

function fetchWithRetry(url, tries) {
    if (tries <= 0) { return Promise.reject('Could not fetch.'); }
    return fetch(url).catch(() => fetchWithRetry(url, tries - 1));
}

// OR:

function fetchWithRetry(url, tries) {
  if (tries <= 0) { throw new Error('Could not fetch.'); }
  const xhr = new XMLHttpRequest();
  xhr.open('GET', url);
  xhr.onerror = () => fetchWithRetry(url, tries - 1);
  xhr.send();
  return xhr;
}

基于Promise的方法要好一些,因为由于应许链接,您的主要代码可以仅假定重试已得到处理,并且可以附加.then(),如果任何尝试成功,它将运行。 .catch()仅在所有尝试均失败的情况下才会运行。使用XHR,它基于事件的性质意味着,如果必须重试,则您的主代码将丢失对当前XHR的引用。