【发布时间】:2017-02-11 00:05:36
【问题描述】:
我想从下面的 html 中知道,如果 link[rel=import]、link[rel=stylesheet]、img 和 script 是 pending/loaded/failed/aborted 而无需添加事前和事件发生后的任何时候的监听器
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta charset="utf-8">
<link rel="import" href="template-bundle.html">
<link rel="stylesheet" href="bundle.css">
</head>
<body>
<header><img src="logo.png" alt="App logo"></header>
<!-- Boilerplate... -->
<script src="./app-bundle.js"></script>
</body>
</html>
换句话说:有没有提供类似于 Bluebird 的 isPending()、isResolved()、isRejected() 方法或常规 ES6 Promise 的接口?
额外问题:这是否可以使用 Service Worker 来实现?
由于 SW 可以拦截请求并知道它们的状态,我想知道我是否可以实现一个返回 Promise 的 API
- 如果请求仍处于未决状态,则处于未决状态
- 如果
load事件被触发则解决
如果 - 将被拒绝。
error 或aborted 被解雇,感谢您的帮助
更新和解决方案:
感谢@pritishvaidya 和@guest271314 的回答,我能够使用MutationObserver 提出一个可行的解决方案,其中包括观察DOM 以添加资源节点(链接、img、脚本)并向它们添加承诺将如上所述解决
这很好用,唯一需要在任何其他资源之前将脚本标记内联到 <head> 中。 Here's an example
var resourceNodeSelector = 'link[href],script[src],img[src]';
function watchResource (n) {
var url = n.href || n.src;
if (!n.matches || !n.matches(resourceNodeSelector)) {
return;
}
if (n.status) {
return;
}
n.status = resourceObserver.promises[url] = new Promise(function (resolve, reject) {
n.addEventListener('load', resolve);
n.addEventListener('error', reject);
n.addEventListener('abort', reject);
n.addEventListener('unload', function (l) { delete resourceObserver.promises[url]} );
});
n.status.catch(function noop () {}); //catch reject so that it doesn't cause an exception
}
var resourceObserver = new MutationObserver(function (mutations) {
document.querySelectorAll(resourceNodeSelector).forEach(watchResource);
});
resourceObserver.promises = {};
resourceObserver.observe(window.document, {childList: true, subtree: true});
一旦观察者就位,任何有效的资源元素都应该有一个status promise 属性,您可以随时检查它
document.querySelector('link').status.then(linkLoaded).catch(linkFailed)
一个更优雅的解决方案,不涉及使用昂贵的querySelectorAll,应该可以使用 ServiceWorker,因为它可以被编程来拦截和跟踪所有资源请求及其状态
【问题讨论】:
-
我对样式不感兴趣。任何触发UI Events 的资源(链接、脚本、img)都将从这样的界面中受益。我提到了 ServiceWorker,因为它们可以拦截请求,所以它们可能能够处理状态并提供类似于我建议的 API
-
我想我会删除样式表链接,因为它会分散人们的注意力
-
不要从您的问题中删除样式表链接,而是在您的示例中添加所有不同类型的加载资源。
-
@trincot 我重组了这个问题,希望更有意义
-
也许你可以参考这个链接,phpied.com/when-is-a-stylesheet-really-loaded
标签: javascript html dom promise