Skip to content

保证 url 打印顺序并支持 retry

已知一个回调形式的 request 接口 (无返回值),和一个链接数组 urlArr

要求:

写一个方法,实现顺序请求数组中的 url,同时保证某一个请求失败后尝试重新请求 3 次,3 次都失败后继续执行下一个请求

js
request(url, (err, data) => {});

const urlArr = [
  "https://www.baidu.com",
  "https://www.google.com",
  "https://github.com",
  "https://www.taobao.com",
];

实现

js
function request(url, fn) {
  console.log(`current url is: ${url}`);
  return fetch(url)
    .then((res) => {
      if (res.ok) {
        console.log(`request url: ${url} is success`);
        fn(null, "ok");
      }
    })
    .catch((err) => {
      fn(new Error(err), null);
    });
}

const urlArr = [
  "https://www.baidu.com",
  "https://www.google.com",
  "https://github.com",
  "https://www.taobao.com",
];

// 核心方法
async function promiseRequestWithRetry(url, retryCount = 1) {
  try {
    const data = await new Promise((resolve, reject) => {
      request(url, (err, data) => {
        if (err) {
          reject(err);
        } else {
          resolve(data);
        }
      });
    });
    return data;
  } catch (error) {
    console.log(`retry url: ${url} count is: `, retryCount);
    if (retryCount < 3) {
      return promiseRequestWithRetry(url, retryCount + 1);
    } else {
      console.log(`retry count is too many, exec next request`);
    }
  }
}

function sequenceRequest(urls, curIndex = 0) {
  if (curIndex >= urls.length) {
    return Promise.resolve("current url is: ", urls[curIndex]);
  }

  return promiseRequestWithRetry(urls[curIndex]).then(() => {
    return sequenceRequest(urls, curIndex + 1);
  });
}

// 开始顺序请求
sequenceRequest(urlArr)
  .then(() => {
    console.log("all request successfully");
  })
  .catch((error) => {
    console.error("request error:", error);
  });