我试图从该模块内的嵌套函数(基本上是一个 xhr 回调(Api.get()
))设置模块变量/属性(在 init()
中) > 函数),但它不起作用,我不明白为什么。
//posts
var Posts = (function() {
//array of all posts objects
var data = null;
//initialize the posts module
var init = function(callback) {
if(data === null) {
//load all posts
loadAll(function(response){
// data = JSON.parse(response)
var posts = JSON.parse(response)
//create array
data = posts;
// call callback
console.log(data)
callback()
})
}
}
// return all posts from api as json
var loadAll = function(callback) {
Api.get('/api/posts/get', function(response) {
callback(response)
})
}
//public interface
return {
data: data,
init: init,
loadAll: loadAll
}
})();
调用 Posts.init()
后,我将 Posts.data
记录到控制台,但它仍然是 null
。但是,init()
方法内的 console.log(data)
会记录我尝试分配给 Posts.data
的预期对象数组。看来回调中的 data
是 Posts.data
之外的另一个变量。有人可以解释一下原因吗?如果可能的话,提供一个在 Api.get()
中设置模块 data
属性的解决方案吗?
最佳答案
您需要拥有对返回对象的引用,以便在返回对象后可以更改其data
属性。一种方法是使用方法和数据创建一个对象并返回该对象。然后您可以使用 this.data
在内部引用其 data
属性:
// Fake API
let Api = {
get(url, cb) {
cb('["testdata"]')
}
}
//posts
var Posts = (function() {
//array of all posts objects
return {
data: null,
init(callback) {
if (this.data === null) {
//load all posts
this.loadAll((response) => { // arrow function needed here for correct `this` binding
var posts = JSON.parse(response)
//create array
this.data = posts; // add data
callback()
})
}
},
loadAll(callback) {
Api.get('/api/posts/get', function(response) {
callback(response)
})
}
}
})();
console.log("initial posts data: ", Posts.data)
Posts.init(() => console.log("After init():", Posts.data))
如果您这样做,那么您实际上并不需要 IEFE,除非您打算制作多个对象。您可以只使用 Posts = {/* 其余数据和方法 */}
。这也可以作为类而不是普通对象很好地工作。
关于javascript - 使用嵌套回调设置js模块的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54258455/