为何使用Promise异步加载两个外部脚本时仅第一个加载成功?
问题描述
尝试等待两个异步加载的外部脚本加载完成,但仅第一个外部脚本成功加载,第二个始终无法加载。调换两个<script>标签顺序后,原本成功的脚本会加载失败,原本失败的脚本则能成功加载。
相关代码
<html> <head> <title>Load Test</title> </head> <body> <script type="text/javascript"> window.gapiLoaded = function () { console.log("window.gapiLoaded, typeof(window.gapiLoadFunc): ", typeof(window.gapiLoadFunc)); if (typeof(window.gapiLoadFunc) == "function") window.gapiLoadFunc(); } window.gisLoaded = function () { console.log("window.gisLoaded, typeof(window.gisLoadFunc): ", typeof(window.gisLoadFunc)); if (typeof(window.gisLoadFunc) == "function") window.gisLoadFunc(); } const gapiPromise = () => new Promise((resolve, reject) => { let x = window.gapiLoadFunc; window.gapiLoadFunc = resolve; console.log("typeof(x):", typeof(x), "typeof(window.gapiLoadFunc):", typeof(window.gapiLoadFunc)) if (typeof(x) == "number") resolve(); }); const gisPromise = () => new Promise((resolve, reject) => { let x = window.gisLoadFunc; window.gisLoadFunc = resolve; console.log("typeof(x):", typeof(x), "typeof(window.gisLoadFunc):", typeof(window.gisLoadFunc)) if (typeof(x) == "number") resolve(); }); async function wait_gapi() { console.log("start wait_gapi") await gapiPromise(); console.log("end wait_gapi") } async function wait_gis() { console.log("start wait_gis"); await gisPromise(); console.log('end wait_gis'); } const wait_gapiPromise = wait_gapi(); const wait_gisPromise = wait_gis(); const waitPromise = Promise.all([wait_gapiPromise, wait_gisPromise]); console.log("calling waitPromise.then()"); waitPromise.then((results) => { console.log("wait done"); return results; }); </script> <script async defer src="https://apis.google.com/js/api.js" onload="console.log('onload gapi'); if (typeof(window.gapiLoaded) == 'function') window.gapiLoaded(); else window.gapiLoadFunc = 0;" </script> <script async defer src="https://accounts.google.com/gsi/client" onload="console.log('onload gsi'); if (typeof(window.gisLoaded) == 'function') window.gisLoaded(); else window.gisLoadFunc = 0;" </script> </body> </html>
JavaScript控制台输出
start wait_gapi test3.html:21 typeof(x): undefined typeof(window.gapiLoadFunc): function test3.html:41 start wait_gis test3.html:29 typeof(x): undefined typeof(window.gisLoadFunc): function test3.html:49 calling waitPromise.then() test3.html:59 onload gapi test3.html:8 window.gapiLoaded, typeof(window.gapiLoadFunc): function test3.html:37 end wait_gapi
问题原因与修复
问题出在外部脚本标签未闭合:你写的两个<script async defer>标签都缺少</script>结尾标签。浏览器的HTML解析器会把第二个脚本标签当成第一个标签的内容,导致第二个脚本从未被加载。调换标签顺序后,第一个脚本(原第二个)能被正常解析,第二个脚本(原第一个)则被当成内容忽略,因此出现相反的加载结果。
修复方法很简单,给每个外部脚本标签加上闭合的</script>:
<script async defer src="https://apis.google.com/js/api.js" onload="console.log('onload gapi'); if (typeof(window.gapiLoaded) == 'function') window.gapiLoaded(); else window.gapiLoadFunc = 0;"> </script> <script async defer src="https://accounts.google.com/gsi/client" onload="console.log('onload gsi'); if (typeof(window.gisLoaded) == 'function') window.gisLoaded(); else window.gisLoadFunc = 0;"> </script>
内容的提问来源于stack exchange,提问作者tedtoal
相关产品推荐
相关产品推荐

