-
Notifications
You must be signed in to change notification settings - Fork 494

Description
AMD is not really asynchronous
The only thing which is asynchronous is the loading of dependencies.
But the definition itself is not really asynchronous. According to the specification the module is defined when factory function is executed and exports is detected.
Bad example:
A module depends on a module which provides only a method to call your callback on a delayed ready state, but your module also wants to provide a ready state.
And what if an other module depends on my example module?
We will run in a crazy chain of such modules ...
define(["domReady"], function (domReady) {
var isReady = false,
cbStack = [];
domReady(function () {
isReady = true;
while (cbStack.length >= 1) {
(cbStack.unshift())();
}
});
return function (callback) {
if (isReady) {
callback();
} else {
cbStack.push(callback);
}
});
});
Asynchronous definition
So the module should be able to say: I'm done.
The defined status of a module should be asynchronous according to the factory function.
The idea of an asynchronous definition is, to delay the detection of exports. If the detection of exports is done, the definition of the module is done too.
Two known implementations
Currently there are 2 pull requests on RequireJS with implementations of asynchronous exports. Both are closed because we should discuss this on the amdjs-api first.
@demurgos - #1078 - A new distinct resolution dependency named delay
define(["delay"], function (delay) {
var Module = {};
setTimeout(function () {
delay(Module);
}, 1000);
});
pro:
- simply to use, just set this dependency, the exports is defined as asynchronous
contra:
- the name of a new distinct resolution dependency could cause conflicts in existing projects
- current implementation doesn't take care for exports priority
@evanvosberg - #1075 - A new property on the module dependency
define(["module"], function (module) {
var asynchronousExports = module.async(),
Module = {};
setTimeout(function () {
asynchronousExports(Module);
}, 1000);
});
pro:
- low risk of conflicts in existing projects by providing a method on the existing distinct resolution dependency module
contra:
- one more call within the factory function to get the asynchronous exporter
Priority of different exports (low - high):
If factory is a function:
- if ["exports"] is in the dependencies list
exports
will be exported - if ["module"] is in the dependencies list
module.exports
will be exported, note thatmodule.exports
andexports
are the same object ifmodule.exports
is not reassigned within the factory - if the call of asynchronousExports hands over one parameter (an object, function, or any value that coerces to true) it will be exported
- if factory function returns a value (an object, function, or any value that coerces to true) it will be exported
If factory is an object
- factory itself will be exported
Indication of support
Additional property on the define.amd
object. Name should be discussed, here is one suggestion.
define.amd = {
async: true
};