Loading module once, requirejs with examples

2019-03-21 01:36发布

问题:

I already ask similar question: Requirejs, what it means "Requirejs loads each module once"
but in that topic no one answer the main question, because i asked in wrong way.

So i will provide some easy examples to show on what i mean:

Module counter.js

1:    define([], function() {
2:        console.log("Executing counter");
3:        var counter = 0;
4:   
5:        return {
6:            increment: function() { counter++; },
7:            get: function() { return counter; }
8:        };
9:    });

Module test1.js

1:    define(['counter'], function(counter) {
2:        console.log("Executing test1");
3:        counter.increment();
4:    });

Module test2.js

1:    define(['counter'], function(counter) {
2:        console.log("Executing test2");
3:        counter.increment();
4:    });

Main.js

1:    require(['test1', 'test2', 'counter'], function(test1, test2, counter) {
2:        console.log("Executing main");
3:        alert(counter.get());
4:    });

So module main.js is entry point of the application which will first load dependencies "test1", "test2" and "counter". (Executing order: Executing counter, Executing test1, Executing test2, Executing main)

So if i understand sentence "Requirejs loads each module once" that means (for example of counter.js) code from line 1 to 9 will be executed ONLY ONCE beside fact that test1, test2 and main module have counter in their dependencies list? If that is correct, test1 is "in charge" for executing counter module? And if that is correct, after executing counter, in memory will be ONLY ONE object which will be returned from counter? When test2 load counter it will get that ONE object? (in another words test2 will not execute again code from counter neither main, they will use existing counter object)? SO, am i creating SINGLETON here?

In the end all of the modules can affect counter value (in beginning, counter = 0) through functions(increment, get) closures? Closures will be alive while counter object exist in memory?

回答1:

I changed your main.js to log to the console

require(['test1', 'test2', 'counter'], function(test1, test2, counter) {
        console.log("Executing main");
        console.log(counter.get());
});

In addition I have an index.html

<!DOCTYPE html>
<html>
<head>
    <title>My Counter Demo</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    <script data-main="scripts/main" src="scripts/require.js"></script>
</head>
<body>
    <h1>My Counter Demo</h1>
</body>
</html>

After loading index.html and then opening the web console I have

[22:04:09.077] "Executing counter"
[22:04:09.077] "Executing test1"
[22:04:09.077] "Executing test2"
[22:04:09.077] "Executing main"
[22:04:09.078] 2 

Log messages

To make it more clear what happens I suggest to substitute the log messages

  • Executing counter -> Creating the counter AMD module
  • Executing test1 -> Incrementing the counter in module "test1"
  • Executing test2 -> Incrementing the counter in module "test2"
  • "Executing main" -> Retrieving the counter value in module "main"

The I get the following result in the console log

[22:16:46.368] file:///C:/Users/User/Documents/requirejs-counter2/css/main.css
[22:16:46.368] file:///C:/Users/User/Documents/requirejs-counter2/scripts/require.js
[22:16:46.369] file:///C:/Users/User/Documents/requirejs-counter2/scripts/main.js
[22:16:46.588] file:///C:/Users/User/Documents/requirejs-counter2/scripts/test1.js
[22:16:46.589] file:///C:/Users/User/Documents/requirejs-counter2/scripts/test2.js
[22:16:46.590] file:///C:/Users/User/Documents/requirejs-counter2/scripts/counter.js
[22:16:46.381] "Creating the counter AMD module"
[22:16:46.381] "Incrementing the counter in module "test1""
[22:16:46.381] "Incrementing the counter in module "test2""
[22:16:46.381] "Retrieving the counter value in module "main""
[22:16:46.381] 2

Conclusion

The counter module is only loaded once and thus creating the counter object only once. You may consider it to be a Singleton.