2017-08-11 96 views
0

我仍然是一个Javascript的noob,我一直在努力包装头脑的一件事是迫使同步成为一种主要是异步编程语言。关于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(); 
} 
加载的JSON,并将它作为目前前 this.guildData填充了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; 
    } 
} 

addLevels功能

guildSelector功能崩溃,因为它找不到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加载要加载的最佳方式。

亲切的问候, 伯爵Lemongrab

+0

*强制同步到一个主要的异步编程语言* - 这不适合你。您必须*拥抱该语言的异步性质。 – Pointy

+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); 
     } 
    }) 
} 

然后改变你的构造利用了承诺:

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

谢谢!这工作完美。我对Promise的语法有点不确定,所以我想避免它们,但它似乎绝对值得更多的阅读。仍然需要等5分钟才能选择这个作为正确的答案,但我会:p –

+1

很高兴帮助伯爵。承诺在很多不同的场景中都非常有用,绝对值得花一些时间学习。欢呼声,祝你好运! :) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise –