如何中止RequireJS'require'请求?

时间:2015-02-04 10:00:55

标签: javascript backbone.js requirejs deferred

是否有可能(以及如何)中止RequireJS require请求?

我希望能够做到这样的事情:

define([
    'Backbone.View'
],
function (BackboneView) {

    var View = BackboneView.extend({

        initialize: function () {

            // store require deferred
            // (I know this is not possible in this way!)
            // Is there a way to capture require deferred?

            this.deferred = require(['someModule'], function () {

                // do something

            });

        },

        close: function () {

            // abort require request if view is closed before request resolves
            this.deferred.abort();

            this.remove()

        }

    });

    return View;

});

因此,如果在require请求结算之前关闭了Backbone View,我希望能够中止require请求。

我已检查过RequireJS文档及其GitHub页面。 没有任何描述如何处理这个问题。

欢迎任何帮助:) TNX

2 个答案:

答案 0 :(得分:1)

RequireJS不提供取消require来电的方法。

我认为理论上可以实现它,但它会使RequireJS的内部由很多复杂化,以获得相当罕见的好处。假设您需要foo,请考虑:

  1. 您的代码实际多久会处于取消require来电的位置?您的视图必须快速初始化并关闭。

  2. 如果在发出foo来电之前已经提取并初始化了require作业require必须做的就是返回对foo的现有引用。所以基本上没有什么可以取消的。请注意,如果视图允许在应用程序中完全初始化一次,则此处考虑的方案适用。

  3. 如果RequireJS足够快,可以在取消前完成require来电,则取消无效。一旦应用程序被优化,RequireJS很可能会在取消之前完成调用。在优化的应用程序中,运行require的代码与所需代码位于同一个包中,因此RequireJS不必从网络中提取任何内容以满足require调用。

  4. 因此,在许多情况下,取消将无效,但对于RequireJS可能必须取消某些内容的情况,它必须仔细考虑谁需要什么。也许您视图中的require电话是唯一需要foo的电话,但foo也可能需要barbaz。如果foo是唯一需要他们的人,那么如果您取消require来电,那么RequireJS可以取消抓取并初始化foobarbaz但是发布 require之后 。所以现在RequireJS必须记住,可以取消bazfoo,但 bar,因为它是在其他地方需要的。

答案 1 :(得分:0)

您的问题有点奇怪,您只会部署一个最小化文件,几乎没有延迟。

对于科学说明,一个require只是将一个脚本元素添加到具有特定比例的DOM中,如data-requiremodule=[MODULE_NAME]  所以你基本上可以这样做:

function abortModuleLoad(moduleName)
    var scripts = document.getElementsByTagName('script');
    for(var i = 0 ; i < scripts.length ; i++){
        if(scripts[i].dataset.requiremodule === moduleName) document.head.removeChild(scripts[i])
    }
}

close: function () {

    // abort require request if view is closed before request resolves
    abortModuleLoad("someModule");

    this.remove()

}