[英]Promise.all with external resolve never resolves
我正在開發一個 SPA(單頁應用程序)項目,需要以動態和受控的方式加載文件(CSS、HTML 和 JS)
我創建了下面的結構(在此示例中僅用於 CSS),但盡管文件被注入到頁面中,但 promise 從未解析
該結構的一個特點是每個創建的“承諾”的“解決”和“拒絕”都保存在原始“承諾”之外執行 function
這是必要的,因為如果“承諾”成功,則必須移除控制事件,如果發生錯誤,則必須移除元素
'use strict';
const
css=
(
()=>
{
const
load=
url=>
{
return new Promise(
(resolve,reject)=>
{
let
link=document.createElement("link");
link.setAttribute("href",url);
link.setAttribute("rel","stylesheet");
link.addEventListener("load",onSuccess);
link.addEventListener("error",onError);
resolveAhead=resolve;
rejectAhead=reject;
document.head.appendChild(link);
}
);
},
onSuccess=
event=>
{
event.target.removeEventListener("load",onSuccess);
event.target.removeEventListener("error",onError);
resolveAhead(event);
},
onError=
event=>
{
document.head.removeChild(event.target);
rejectAhead(event);
};
let
resolveAhead,
rejectAhead;
return {
load
}
}
)();
Promise.all(
[
css.load("style1.css"),
css.load("style2.css"),
css.load("style3.css"),
css.load("style4.css"),
css.load("style5.css"),
css.load("style6.css")
]
).then(
response=>
{
console.log(response);
alert("Well done");
}
).catch(
response=>
{
console.log(response);
alert("Houston... we've had a problem here");
}
);
您的問題是您有兩個變量:
let resolveAhead, rejectAhead;
第一次調用.load()
時,將它們設置為正在構建的新 Promise 的解析和拒絕函數。 但是,下次調用.load()
時,您將再次創建一個新的 Promise,並覆蓋這些變量以解決/拒絕新的 Promise。 然后只能調用最后構造的 Promise 中的解析/拒絕函數。
您可以在您的load()
function 中創建對這些的引用,以便進一步調用load()
不會影響已經定義的 resolveAhead 和 rejectAhead 函數:
'use strict'; const css = (() => { const load = url => { let resolveAhead, rejectAhead; const onSuccess = event => { event.target.removeEventListener("load", onSuccess); event.target.removeEventListener("error", onError); resolveAhead(event); }; const onError = event => { document.head.removeChild(event.target); rejectAhead(event); }; return new Promise( (resolve, reject) => { let link = document.createElement("link"); link.setAttribute("href", url); link.setAttribute("rel", "stylesheet"); link.addEventListener("load", onSuccess); link.addEventListener("error", onError); resolveAhead = resolve; rejectAhead = reject; document.head.appendChild(link); } ); }; return {load}; })(); Promise.all([ css.load("https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"), css.load("https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css"), ]).then(response => { console.log(response); alert("Well done"); }).catch(response=> { console.log(response); alert("Houston... we've had a problem here"); });
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.