对Javascript回调函数/承诺的困惑

时间:2017-08-11 14:33:49

标签: javascript function callback

我在Javascript上仍然是一个非常棒的人,而我正在努力解决的一件事就是强制同步到主要的异步编程语言。

我有一个加载一个体面大小的JSON文件的函数和另一个利用这个函数返回的函数。

我已经阅读了很多关于类似问题的其他主题并且一直看到非常不同的解决方案,我只是好奇最好的办法是什么。

构造函数调用这两个函数 -

class Guild extends MapObject {
constructor(x,y,floor,type,name) {
    super(x,y,floor);
    this.levels = [];
    this.type = type;
    this.name = name;
    this.guildSelector();
    this.addLevels(this.name); 
    this.setTip();
}

guildSelector函数,用于加载JSON并将其作为this.guildData

返回
guildSelector(){
    var oReq = new XMLHttpRequest();
    this.guildData = null;

    oReq.onload = reqListener;
    oReq.open("get", "/json/guilds.json", true);
    oReq.send();

    function reqListener() {
        this.guildData = JSON.parse(this.responseText);
        console.log(this.guildData);
        return this.guildData;
    }
}

当前在this.guildData之前运行的addLevels函数使用JSON填充,导致它崩溃,因为它找不到null的.guilds。

addLevels(name) {  

    if(name == "default"){
        this.name = "lowerSchoolOfEndurance";
    }

    console.log(this.guildData);

    this.guildData.guilds.forEach(function(guild) {
        console.log(guild.name);
        if(guild.name == name){
            for(var i = 1; i <= guild.levels.length; i++){
                var guildStats = guild.levels[i-1];
                for (var k in guildStats) {
                    console.log("Level "+i+" of the guild "+name+" increases "+k+" stat by "+guildStats[k]);
                    this.levels.push(guild.levels[i-1]);
                }
            }
        }
    });
    return this.levels;
}

所以TL:DR基本上就是,在JSON加载之前,不需要加载JSON的最佳方法是什么是最好的方法。

亲切的问候, Earl Lemongrab

1 个答案:

答案 0 :(得分:2)

您应该使用Promise s:

guildSelector(){
    return new Promise((resolve, reject) => {
       var oReq = new XMLHttpRequest();
       this.guildData = null;

       oReq.onload = reqListener;
       oReq.open("get", "/json/guilds.json", true);
       oReq.send();

       function reqListener() {
          this.guildData = JSON.parse(this.responseText);
          resolve(this.guildData);
       }
   })
}

然后更改构造函数以使用Promise:

this.guildSelector().then((guildData) => {
   this.guildData = guildData;
   this.addLevels(this.name);
});