如何通过重试和 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);
我想实现一个动态加载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);