【问题标题】:How do I cancel a promise inside the "done" callback?如何在“完成”回调中取消承诺?
【发布时间】:2014-06-05 22:51:49
【问题描述】:

我有以下场景...

$.when(
    $.getScript('script.js')
).done(function () {
    if ( scriptIsAlreadyLoaded ) {
        // I want to cancel this promise.
        // I no longer want script.js because
        // it has already been loaded in another
        // instance.
    }

    // I dont' want this to run if the above
    // condition is true.
    doStuff();
});

我知道在 done() 内部这样做没有多大意义,因为根据定义,取消承诺为时已晚。

那么这里最好的方法是什么?

注意:这个 sn-p 可以执行多次。这就是为什么我想避免脚本被多次加载。

【问题讨论】:

  • 呃……在完成里面已经……完成了。我根本不明白你想要完成什么。只需保留一个布尔标志并用if 包围$.when
  • 使用 $.getScript 会自动解析脚本,所以即使你取消它,它也已经被加载了,所以这没有任何意义。
  • 另外,除了@adeneo 所说的浏览器缓存脚本(除非您的服务器发送不正确的缓存头),所以它不会再次发出请求。
  • 另外,它似乎可以像 -> jsfiddle.net/y76Be
  • @BenjaminGruenbaum,我知道它在 done() 函数中没有意义(我在帖子中承认了这一点)。我希望我能得到一个真正有意义的替代方案的建议。

标签: jquery promise jquery-deferred cancellation


【解决方案1】:

.done() 处理程序中取消承诺是没有意义的。当.done() 处理程序被调用时,操作已经完成(听起来你可能已经知道了)。因此,当您的 .done() 处理程序被调用时,您的脚本的加载已经完成。没有什么可以取消的。

如果您只是想防止自己的代码尝试多次加载脚本,那么您实际上并没有为此使用 Promise。您可以只跟踪自己的标志,也可以测试环境以查看脚本是否已经存在。例如,您可以使用这个函数来检查是否已经加载了一个以特定文件名结尾的脚本标签:

function isScriptPresent(fname) {
    var regex = new RegExp(fname + "$");
    var scripts = document.getElementsByTagName("script");
    for (var i = 0; i < scripts.length; i++) {
        if (regex.test(scripts[i].src)) {
            return true;
        }
    }
    return false;
}

if (!isScriptPresent("script.js")) {
    $.getScript("script.js");
}

或者,您可以创建自己的 getScript 函数,首先检查它是否已经加载:

$.getScriptIfNotLoaded = function(fname) {
    if (!isScriptPresent(fname)) {
        return $.getScript(fname);
    }
}

那么,你可以这样做:

$.getScriptIfNotLoaded("script.js");

而且,它永远不会在同一页面中多次加载。这样做的好处是,脚本的首次加载方式无关紧要(即使它是在原始 HTML 中) - 如果它已经在页面中,它将找到它。


您也可以只跟踪地图中加载的内容:

(function() {
    var loadedScripts = {};

    $.loadScriptOnce = function(fname) {
        if (!loadedScripts[fname]) {
            loadedScripts[fname] = true;
            return $.getScript(fname);
        }
    };
})();

$.loadScriptOnce("scripts.js");

【讨论】:

    猜你喜欢
    • 2015-08-07
    • 2022-06-24
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    • 2017-02-14
    相关资源
    最近更新 更多