有没有办法知道链接/脚本是否仍在等待或失败 [英] Is there a way to know if a link/script is still pending or has it failed

查看:18
本文介绍了有没有办法知道链接/脚本是否仍在等待或失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从下面的html中知道,如果link[rel=import]link[rel=stylesheet]img> 和 script挂起/加载/失败/中止,无需事先和在事件发生后的任何时候添加侦听器

I'd like to know from the html below, if link[rel=import], link[rel=stylesheet], img and script are pending/loaded/failed/aborted without the need to add listeners beforehand and at any point after the event has happened

<!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?

In other words: Is there an interface which provides something similar to a Bluebird's isPending(), isResolved(), isRejected() methods or a regular ES6 Promise?

额外问题:这可以使用 Service Worker 实现吗?

Bonus question: Is this something can be achieved using a Service Worker?

由于 SW 可以拦截请求并知道它们的状态,我想知道我是否可以实现一个返回 Promise 的 API

Since SW can intercept requests and know their status, I was wondering if I can implement an API which returns a Promise that

  • 如果请求仍处于待处理状态,则处于待处理状态
  • load 事件触发时被解决
  • 如果 erroraborted 被触发,
  • 被拒绝.
  • is pending if request is still pending
  • is resolved if load event fired
  • is rejected if error or aborted was fired.

感谢您的帮助

更新&解决方案:

感谢@pritishvaidya 和@guest271314 的回答,我能够使用MutationObserver 涉及观察 DOM 中是否添加了资源节点(链接、img、脚本),并向它们添加承诺,该承诺将按上述方式解析

Thanks to the answers of @pritishvaidya and @guest271314, I was able to come up with a viable solution using MutationObserver that involves watching DOM for additions of resource nodes (link,img,script) and adding a promise to them that will resolve as described above

这很好用,唯一的问题是脚本标签需要在任何其他资源之前内联在 中.这是一个例子

This works great, with the only caviat that the script tag needs to be inlined in <head> before any other resource. 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 承诺属性,您可以在任何时间点检查

Once the observer is in place, any valid resource element, should have a status promise property that you can check at any point in time

document.querySelector('link').status.then(linkLoaded).catch(linkFailed)

一个更优雅的解决方案,不涉及使用昂贵的querySelectorAll,应该可以通过 ServiceWorker 实现,因为它可以被编程来拦截和跟踪所有资源请求及其状态

A more elegant solution, that does not involve using the expensive querySelectorAll, should be possible with ServiceWorker, since it can be programmed to intercept and keep track of all resource requests and their status

推荐答案

你可以利用onloadonerror事件元素;请参阅右栏中的浏览器 CSS/JS 加载功能.

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

创建一个对象来存储所有 请求的状态,以及对应于 元素的已解决或拒绝的 Promise.

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

onerror 事件中拒绝Promise;使用链接到 Promise.reject().catch() 来处理错误,以便 Promise.all() 不会停止处理已解决的承诺数组作为参数传递.如果任何被拒绝,您也可以从 .catch()onerror 处理程序中 throw 错误到 Promise.all()Promise 应该停止处理 promise 数组中已解决的 promise.

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.

window.onload 事件处理程序中,使用 Promise.all() 处理所有解析的链接,使用在 window.onload 之前调用的相同函数> 事件.要等待 Promise.all() 的结果可用,请将最后一个

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆