javascript - 使用嵌套回调设置js模块的属性

标签 javascript module scope callback

我试图从该模块内的嵌套函数(基本上是一个 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 的预期对象数组。看来回调中的 dataPosts.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/

相关文章:

python - 重命名内置的 python 方法,如 replace()

python - 没有名为 'xxx' 的模块; 'yyy' 不是一个包

ruby-on-rails - 按两个属性排序,其中一个在子模型中(rails 4)

javascript - 函数中未声明的 JavaScript 变量覆盖了使用

javascript - 外部 JavaScript 可以访问不同文件中的 DOM 元素吗?

javascript - 如何在执行嵌入式脚本时仅插入使用 $.ajax() 加载的完整页面的一部分?

Python-kivy 问题

javascript - 停止 jQuery 函数在页面加载时运行

javascript - backbone.js - 简单 View

javascript - 复选框不想切换启用禁用字段