我已经定义了一个模块(module1),它应该异步加载属性的值。我如何才能在我的应用程序中使用这个属性,一旦它被定义并且只有在它被定义之后?
我的设置(简化)
v1
应用程序.js
require(['module1'], function(mod) {
document.getElementById("greeting").value = mod.getPersonName();
});
模块1.js
define(['jquery'], function($) {
_person;
$.get('values/person.json')
.done(function(data) {
_person = data
});
return {
getPersonName: function() { return _person.name; }
}
值/person.json
{ name: 'John Doe', age: 34 }
这仅在 GET 几乎瞬间发生时才有效,否则它会失败,因为在调用 getPersonName 时 _person 未定义。
v2
为了解决这个问题,我想我会注册一个回调,以便在加载人员时通知应用程序。
应用程序.js
require(['module1'], function(mod) {
mod.onPersonLoaded(function() {
document.getElementById("greeting").value = mod.getPersonName();
});
});
模块1.js
define(['jquery'], function($) {
_person;
_onLoaded;
$.get('values/person.json')
.done(function(data) {
_person = data;
_onLoaded();
});
return {
getPersonName: function() { return _person.name; },
onPersonLoaded: function(cb) { _onLoaded = cb; }
}
}
如果 GET 很慢,这可以工作,但是,如果它很快 _onLoaded 在.done()
被调用时是未定义的。
有没有一种好方法可以在定义后立即在 app.js 中使用 _person 值,并且仅在定义后才使用?
我正在使用 RequireJS,但我的问题通常适用于 AMD。
编辑
为了简化我的示例,我删除了一个可能很重要的层。我正在为 UI 使用 RactiveJS。
设置(稍微简化)
应用程序.js
require(['Ractive', 'module1'], function(Ractive, mod) {
var ractive = new Ractive({
...
data : {
name: mod.getPersonName()
}
});
ractive.observe(...);
ractive.on(...);
});
编辑 2
我目前的解决方案,可能会发生变化。注册一个回调,在加载人员时通知 app.js。如果在注册回调时已加载人员,则立即调用回调。
应用程序.js
require(['Ractive', 'module1'], function(Ractive, mod) {
var ractive = new Ractive({
...
data : {}
});
mod.watchPerson(function() {
ractive.set('person.name', mod.getPersonName());
});
ractive.observe(...);
ractive.on(...);
});
模块1.js
define(['jquery'], function($) {
_person;
_onLoaded;
$.get('values/person.json')
.done(function(data) {
_person = data;
try {
_onLoaded();
} catch (e) {
// that was fast!
// callback will be called when it is registered
});
return {
getPersonName: function() { return _person.name; },
watchPerson: function(cb) {
_onLoaded = cb;
if(_person != null) {
_onLoaded();
}
}
}
}