如何通过重试和 returns 实现动态加载的脚本功能

How to implement dynamically loaded script functionality with retries and returns

我想实现一个动态加载js脚本的功能,加载失败重试,重试次数限制为3次,return加载结果

async function getScript(url: string, retryTime = 0, promise?: any) {
  const element = window.document.createElement('script');
  element.src = url;
  element.type = 'text/javascript';
  element.async = true;

  const p = promise || {
    resolve: (v: boolean) => { },
    reject: (msg: string) => { },
  };

  element.onload = () => {
    p.resolve(true);
  };

  element.onerror = () => {
    const msg = `Dynamic Script Error: ${url}`;
    if (retryTime < 3) {
      console.log('retry load');
      document.head.removeChild(element);
      return getScript(url, retryTime + 1, p);
    }
    p.reject(msg);
  };
  document.head.appendChild(element);
  return new Promise((rl, rj) => {
    p.resolve = rl;
    p.reject = rj;
  });
}

但是我调用这个函数的时候,如果第一次加载出错,第二次加载成功。 document.head.appendChild(element)会抛出错误,因此,我无法在外部捕获错误。

我能做什么。

似乎太复杂了。这是一个更简洁、更解耦的解决方案:

async function getScript(url) {
  return new Promise((resolve, reject) => {
    const element = document.createElement('script');
    element.src = url;
    element.type = 'text/javascript';
    element.async = true;
    element.onload = () => resolve();
    element.onerror = () => reject();
    document.head.appendChild(element);
  });
}

async function retrying(func, attempts) {
  for (let attempt = 1; attempt <= attempts; attempt++) {
    try {
      return await func();
    } catch (ex) {
      console.warn(`Failed in attempt ${attempt}`);
    }
  }
  throw new Error(`Failed after ${attempts} attempts`);
}

用法:

retrying(() => getScript(url), 3);