簡體   English   中英

Promise.all 與外部解析永遠不會解決

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM