【问题标题】:Assuring a callback for an async script确保异步脚本的回调
【发布时间】:2016-02-21 19:04:30
【问题描述】:

我必须加载一个对显示正文并不重要的第三方脚本(为简单起见,它在“.red”div 上添加了红色背景)。

<script src="redify.js" async defer></script>

脚本加载后我需要执行function myRedify(){ $(".red").redify(); }

脚本很大,需要很长时间(比如 3 秒)才能加载,但一旦完成,我需要看到我的 .red div 变成红色。

<script src="redify.js" async defer onload="myRedify()"></script>

这是推荐的方法吗?

备注

  • redify.js 是我无法修改的第三方脚本
  • 我不介意 div 不是立即变红,而是在延迟之后(加载脚本时,3 秒 - 好)

【问题讨论】:

  • 脚本加载后会立即执行,所以你可以把myPostFunction()放在脚本末尾。
  • @r3wt,OP正在询问推荐方式!
  • 公平地说,他问这是否是推荐的方式,而不是上面的代码是否可行:)
  • @ins0 这是唯一可能的方法,除非您在 javascript 中以编程方式创建脚本并执行 script.onload = function(){...,或者正如 @Halcyon 所说,只需在脚本底部调用您的函数。
  • 如果您的脚本 B 依赖于脚本 A,请不要使脚本 A 异步。那会招来麻烦。始终以同步方式加载它们。

标签: javascript html asynchronous


【解决方案1】:

你的方法行之有效,因此它有优点。推荐吗?可能是。 您的方法有一些优点和一些缺点:

  • 性能:立即开始加载 redify 脚本
  • 可读性:只看 HTML 就很明显发生了什么
  • 缺点是,如果您要添加另一个库(例如:blueify.js),则必须复制该机制。

现在您的代码通过myRedify 函数紧密耦合。你可以通过构建一个简单的require 策略来解耦它:

var libraries = {
    redify: "redify.js",
    blueify: "blueify.js"
};
var lib_bookkeep = {};

function require(library_name, callback) {
    if (lib_bookkeep[library_name]) {
         if (lib_bookkeep[library_name].status === "loaded") {
             callback();
         } else {
             lib_bookkeep[library_name].elem.addEventListener("load", callback);
         }
    } else {
        var script = document.createElement("script");
        script.src = libraries[library_name];
        script.addEventListener("load", function () {
            lib_bookkeep[library_name].status = "loaded";
        });
        script.addEventListener("load", callback);
        document.head.appendChild(script);
        lib_bookkeep[library_name] = {
            elem: script
            status: "loading"
        }
    }
}

require("redify", function () {
    $(".red").redify();
});

require("redify", function () {
    $(".also-red").redify();
});

require("blueify", function () {
    $(".blue").redify();
});
require("blueify", function () {
    require("redify", function () {
        $(".purple").redify().blueify();
    });
});

这允许您扩展您拥有的库,并且允许您任意使用它们。这将采用我推荐的方法。但是,如果您只有这个实例,它可能会像您一样使用asynch/deferonload

【讨论】:

  • “添加脚本包含并在加载后调用任何回调”到底是什么意思是 ajax 调用吗?
  • @Serge 我添加了一个示例实现。我还没有测试过,但理论上它应该可以工作。
猜你喜欢
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
  • 1970-01-01
  • 2021-06-24
  • 1970-01-01
相关资源
最近更新 更多