动态加载rel=gettext的link资源时Promise始终pending?如何解决?
动态添加rel="gettext"的link标签时Promise无法resolve的问题
我尝试用JavaScript动态加载脚本、CSS及文本资源,CSS加载的Promise能正常完成,但添加rel为gettext、type为application/x-po的link标签时,Promise一直处于pending状态——虽然标签已经成功添加到head里,但就是不触发onload或onerror事件。
正常工作的CSS加载代码
function linkCSS(url) { var head = document.getElementsByTagName('head')[0]; return new Promise(function (resolve, reject) { let link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = url; link.onload = function () { resolve(url); }; link.onerror = function () { reject(url); }; head.appendChild(link); }); }; let promised = [linkCSS("javascripts/jquery-ui.css")]; console.log('promisedCSS', promised); Promise.all(promised).then(function () { }).catch((reason) => { console.log(reason); });
无法正常resolve的gettext link加载代码
要添加的静态标签:
<link rel="gettext" type="application/x-po" href="javascripts/node_modules/country-region-dropdown-menu/languages/en/LC_MESSAGES/en.po">
对应的动态加载函数:
function linkGettext(url) { var head = document.getElementsByTagName('head')[0]; return new Promise(function (resolve, reject) { let link = document.createElement('link'); link.rel = 'gettext'; link.type = 'application/x-po'; link.href = url; link.onload = function () { resolve(url); }; link.onerror = function () { reject(url); }; head.appendChild(link); }); }; let promised = [linkGettext("javascripts/node_modules/country-region-dropdown-menu/languages/en/LC_MESSAGES/en.po")]; console.log('promisedGETTEXT', promised); Promise.all(promised).then(function () { }).catch((reason) => { console.log(reason); });
解决方案
问题核心是:浏览器只会对自身识别并主动加载解析的资源类型(比如stylesheet、script)触发onload/onerror事件,而rel="gettext"属于自定义rel类型,浏览器不会主动加载该资源,自然不会触发事件,导致Promise一直pending。
根据需求场景,有两种解决方式:
场景1:需要确保PO文件已成功加载
用fetch主动发起请求验证资源可用性,成功后再添加标签并resolve Promise:
function linkGettext(url) { var head = document.getElementsByTagName('head')[0]; return new Promise(function (resolve, reject) { fetch(url) .then(response => { if (!response.ok) throw new Error('资源加载失败'); return response.text(); }) .then(() => { let link = document.createElement('link'); link.rel = 'gettext'; link.type = 'application/x-po'; link.href = url; head.appendChild(link); resolve(url); }) .catch(() => reject(url)); }); };
场景2:仅需添加标签,无需验证资源加载
直接在标签添加完成后立即resolve:
function linkGettext(url) { var head = document.getElementsByTagName('head')[0]; return new Promise(function (resolve, reject) { let link = document.createElement('link'); link.rel = 'gettext'; link.type = 'application/x-po'; link.href = url; head.appendChild(link); resolve(url); }); };
内容的提问来源于stack exchange,提问作者mchlmchl
相关产品推荐
相关产品推荐

