gpt4 book ai didi

javascript - 异步加载模块属性

转载 作者:行者123 更新时间:2023-12-02 17:50:41 24 4
gpt4 key购买 nike

我定义了一个模块(module1),它应该异步加载属性的值。如何在定义后立即在我的应用程序中使用此属性?

我的设置(简化)

v1

app.js

require(['module1'], function(mod) {
document.getElementById("greeting").value = mod.getPersonName();
});

module1.js

define(['jquery'], function($) {
_person;

$.get('values/person.json')
.done(function(data) {
_person = data
});

return {
getPersonName: function() { return _person.name; }
}

values/person.json

{ name: 'John Doe', age: 34 }    

这仅在 GET 几乎瞬时发生时才有效,否则会失败,因为调用 getPersonName 时 _person 未定义。

v2

为了解决这个问题,我想我应该注册一个回调来在加载人员时通知应用程序。

app.js

require(['module1'], function(mod) {
mod.onPersonLoaded(function() {
document.getElementById("greeting").value = mod.getPersonName();
});
});

module1.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 速度较慢,则此方法有效,但如果速度较快,则在调用 .done() 时 _onLoaded 未定义。

有没有一种好方法可以在 app.js 中一旦定义并仅在定义后使用 _person 值?

我正在使用 RequireJS,但我的问题通常适用于 AMD。

编辑

在简化我的示例时,我删除了一个可能很重要的层。我使用 RactiveJS 作为 UI。

设置(稍微简化)

app.js

require(['Ractive', 'module1'], function(Ractive, mod) {

var ractive = new Ractive({
...
data : {
name: mod.getPersonName()
}
});

ractive.observe(...);
ractive.on(...);

});

编辑2

我当前的解决方案,可能会发生变化。注册一个回调,在加载 person 时通知 app.js。注册回调时,如果人员已经加载,则立即调用回调。

app.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(...);

});

module1.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();
}
}
}
}

最佳答案

Promise 在这里是一个不错的选择,因为回调总是异步调用 - 您永远不会遇到 _onLoaded() 在设计之前就被调用的困惑情况。

不幸的是,jQuery 的 Promise 实现并不遵守 Promises/A+ specification ,所以你得不到这个保证。如果可能,您可以使用替代 AJAX 库,例如 Reqwest ,然后做类似的事情

app.js

define(['module1'], function (mod) {
mod.then(function(person) {
// do something with person.name
}
});

module1.js

define(['reqwest'], function (reqwest) {
return reqwest('values/person.json');
});

使用文本加载器插件

由于您已经在使用 AMD,另一个选择是使用加载器插件,例如 text :

app.js

define(['module1'], function (person) {
// do something with person.name
});

module1.js

define(['text!values/person.json'], function (personJSON) {
return JSON.parse(personJSON);
});

使用文本加载器插件

事实上甚至还有一个JSON plugin ,因此在此示例情况下您可以完全取消 module1:

app.js

define(['json!values/person'], function (person) {
// do something with person.name
});

关于javascript - 异步加载模块属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21390684/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com