Is there a way to know if a link/script is still pending or has it failed

You can utilize onload, onerror events of <link> element; see Browser CSS/JS loading capabilities at right column.

Create an object to store status of all <link> requests and resolved or rejected Promise corresponding to the <link> element.

Reject Promise at onerror event; use .catch() chained to Promise.reject() to handle error so that Promise.all() will not stop processing resolved promises within array passed as parameter. You can also throw error from .catch() at onerror handler to Promise.all() if any rejected Promise should stop processing of resolved promise within array of promises.

At window.onload event handler, use Promise.all() to process all resolved links, using same function called before window.onload event.
To wait for results of Promise.all() to be available, set src of last <script> element to bundle.js at .then() chained to Promise.all()

<!DOCTYPE html>
<html>

<head>
  <title>App</title>
  <meta charset="utf-8">
  <script>
    var handleLinks = {
      links: [],
      isPending: true
    };

    function handleBeforeLoad() {
      if (document.querySelectorAll("link").length === 0) {   
        console.log("links loading state is pending..", handleLinks.isPending);
      } else {
        handleLinks.isPending = false;
        Promise.all(handleLinks.links)
          .then(function(linksContent) {
            console.log("links resolved:", linksContent
                       , "links loading state is pending.."
                       , handleLinks.isPending);
            linksContent.filter(Boolean).forEach(function(link) {
              // `content` property : html `document`,  `CSSStyleSheet` 
              // requested at `<link>` element
              console.log(link); 
            });
            // load `bundle.js`
            document.getElementById("bundle")
            .src = "https://stackoverflow.com/questions/39824927/bundle.js"

          })
          .catch(function(err) {
            console.log("link error:", err.message)
          })
      }
    }
    handleBeforeLoad();
    window.onload = handleBeforeLoad;

    function handleLink(el) {
      handleLinks.links.push(Promise.resolve({
        content: el.import || el.sheet,
        type: el.type,
        rel: el.rel,
        href: el.href,
        integrity: el.integrity,
        isResolved: true
      }));

    }

    function handleLinkError(el) {
      handleLinks.links.push(Promise.reject(new Error(JSON.stringify({
        error: "error loading link",
        type: el.type,
        rel: el.rel,
        href: el.href,
        integrity: el.integrity,
        isRejected: true
      }))).catch(function(err) {
        // handle error
        console.log(err);
        // this will return a resolved Promise
        return "error requesting link " + el.href;
        // `throw err` here if any rejected Promise should
        // stop `Promise.all()` from handling resolved Promise
      }));

    }
  </script>
  <link onload="handleLink(this)" 
        onerror="handleLinkError(this)" 
        rel="import" 
        href="https://stackoverflow.com/questions/39824927/template-bundle.html" 
        type="text/html">
  <link onload="handleLink(this)" 
        onerror="handleLinkError(this)" 
        rel="stylesheet" 
        href="bundle.css" 
        type="text/css">
  <!-- this should throw error, file does not exist -->
  <link onload="handleLink(this)" 
        onerror="handleLinkError(this)" 
        rel="stylesheet" 
        href="bundles.css" 
        type="text/css">

  <body>
    <header><img src="" alt="App logo"></header>
    <!-- Boilerplate... -->
    <script id="bundle"></script>
  </body>

</html>

plnkr http://plnkr.co/edit/DQj9yTDcoQJj3h7rGp95?p=preview

Leave a Comment