Javascript 承诺本身有时间吗?如果承诺在特定的时间段内从未得到解决,它最终会“拒绝”自己吗?
我之所以想到这一点,是因为我写了一个小脚本标签,通过承诺从第三方服务获取脚本来加载脚本。我在想,如果第三方服务将在不放弃备份结果的情况下持续加载,那么该承诺会发生什么?有没有解决这种边缘案件的办法?向整个loadScript添加超时是最聪明的方法吗Javascript 承诺本身有时间吗?如果承诺在特定的时间段内从未得到解决,它最终会“拒绝”自己吗?,javascript,asynchronous,promise,xmlhttprequest,script-tag,Javascript,Asynchronous,Promise,Xmlhttprequest,Script Tag,我之所以想到这一点,是因为我写了一个小脚本标签,通过承诺从第三方服务获取脚本来加载脚本。我在想,如果第三方服务将在不放弃备份结果的情况下持续加载,那么该承诺会发生什么?有没有解决这种边缘案件的办法?向整个loadScript添加超时是最聪明的方法吗 function loaderScript(scriptUrl){ return new Promise(function (res, rej) { let script = document.createEl
function loaderScript(scriptUrl){
return new Promise(function (res, rej) {
let script = document.createElement('script');
script.src = scriptUrl;
script.type = 'text/javascript';
script.onError = rej;
script.async = true;
script.onload = res;
script.addEventListener('error',rej, { once: true });
script.addEventListener('load',res, { once: true });
document.head.appendChild(script);
})
}
loaderScript('https://...com').then(() => {...}).catch(() => { ... })
承诺本身有时间吗?如果承诺在特定时间内从未得到解决,它最终会拒绝承诺本身吗
承诺没有内置的超时。如果没有什么可以解决或拒绝它们,它们将永远处于“待定”状态
如果需要,您可以构建自己的超时
function loaderScript(scriptUrl) {
return new Promise(function(res, rej) {
const TIMEOUT = 5 * 1000;
let timer = setTimeout(function() {
rej(new Error("Script load timeout"));
}, TIMEOUT);
let script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.addEventListener('error', function(e) {
rej(e);
clearTimeout(timer);
});
script.addEventListener('load', function() {
res();
clearTimeout(timer);
});
script.src = scriptUrl;
document.head.appendChild(script);
})
}
但是,浏览器在发出请求时确实有超时,因此插入脚本标记最终会触发加载
或错误
事件。浏览器超时有时可能很长,而且不是标准超时(不同浏览器的超时可能不同),因此添加自己控制的超时通常很有用
关于代码的其他一些注释:
.onError
和侦听错误事件。挑一个或另一个
一次:true
。首先,加载和错误事件不会被调用多次。第二,即使他们这样做了,在这里也没有什么坏处,因为承诺只能解决或拒绝一次。一旦您解决或拒绝了它,它们将被锁定,然后调用res()
或rej()
将不会执行任何操作.src
属性设置为最后一个总是最安全的,这样就不会错过任何事件如果您愿意,您可以添加一个超时。“持续加载而不放弃备份结果”是什么意思?@jfriend00 iow,api速度很慢,它试图从api检索数据,但从未得到响应,同时也从未长时间失败。