Run action after all requirejs modules are loaded

2019-06-19 07:26发布

问题:

There are several modules on page:

// module 1
require(['signalr'], function(s) {
    s.subscribe('myhub1', function () { /* some code */ });
});

// module 2
require(['signalr'], function(s) {
    s.subscribe('myhub2', function () { /* some code 2 */ });
});

And there is method that should be invoked after all modules are invoked (all subscribtions are done):

require(['signalr'], fuinction (s) { s.connect(); });

The possible solution is define modules and write like this:

// module 1
define('module 1', ['signalr'], function(s) {
    s.subscribe('myhub1', function () { /* some code */ });
});

// module 2
define('module 2', ['signalr'], function(s) {
    s.subscribe('myhub2', function () { /* some code 2 */ });
});
require(['signalr', 'module 1', 'module 2'], fuinction (s) { s.connect(); });

But the problem is that different pages has different modules, say:

page1.cshtml: module 1

page2.cshtml: module 1, module 2

So I can't write: require(['signalr', 'module 1', 'module 2'], fuinction (s) { s.connect(); }); because module 2 may not be defined on page2.cshtml.

回答1:

The best way would be to conditionally build an array and pass it through to the require function and then run your completion in the callback as you mentioned in the question.

var modulesToLoad = [];

// Build the array

require(modulesToLoad, function (s) { 
    s.connect(); 
});

If for some reason you can't aggregate your calls into a single require you will need to keep track of modules to load and run a check on completion that all have loaded, then run your clean up code

var checkIfLoaded = {
    myhub1 : false,
    myhub2 : false,
    myhub3 : false
}

function checkIfReady(s) {
    for (var prop in checkIfLoaded) {
        if ( ! checkIfLoaded[prop] ) {
            return false;
        }
    }

    // Completion code
    s.connect();
}

require(['myhub1'], function(s) {
    checkIfLoaded.myhub1 = true;
    checkIfReady(s);
});

require(['myhub2'], function(s) {
    checkIfLoaded.myhub2 = true;
    checkIfReady(s);
});

Thinking about this, you should be able to build a requirements array