繁体   English   中英

仅在第一个功能完全完成后如何运行第二个Javascript功能?

[英]How to run second Javascript function only after first function fully completes?

我正在使用HTML和Javascript创建一个Facebook游戏,并且我刚刚完成了一个排行榜表,该表列出了每个玩家的姓名和排名。 该表填充了从Facebook游戏分数API返回的数据。

这是完美的工作方式,但我也想奖励提高他们在表中排名的球员。

我打算这样做:

  • 当游戏加载时,我运行一个名为updateTable();的函数updateTable(); ,则使用从对Facebook数据库的API调用中接收到的球员的得分和排名来填充排行榜。
  • 当玩家开始玩游戏时,我将其等级的副本存储在单独的隐藏div中。
  • 游戏结束时,如果玩家达到了新的高分,则将其输入数据库。 发生这种情况后,我运行updateTable(); 再次更新排行榜。
  • 然后,我运行一个名为compareRanks();的函数compareRanks(); ,这会将玩家的新排名与我存储在隐藏div中的排名进行比较。

如果新排名比存储的排名低,那么他们已经升至排行榜前列,我为他们每上升一个位置奖励100个硬币。

例如:

玩家A开始游戏并排名第5(因此,“ 5”将存储在隐藏的div中)。 当玩家A完成游戏时,排行榜将更新,并且玩家A现在排名第二(因此玩家跳了3位)。

为了弄清楚奖励应该是多少,我想从第二个变量中减去第一个变量(5-2 = 3),玩家A超越了其他3个玩家,所以他们的奖励将是3 x 100金币。

我遇到的问题是,当我运行compareRanks(); ,即使我知道玩家已经提高了自己的排名,新排名也会一直与存储的排名相同。

我很确定这是由于在updateTable();之前获得了新的排名updateTable(); 已与数据库完全交互。 我已经通过分离功能,进行compareRanks();测试了这一点compareRanks(); 只需单击一下按钮,当我这样做时,我完成了游戏,提高了排名,在updateTable();之后等待了几秒钟updateTable(); 运行,然后单击按钮,两个等级显示的不同,这是正确的。 所以我认为compareRanks(); 只需要等待updateTable(); 在运行之前完全完成。

这是我的功能布局的方式:

updateTable(){
//code here interacts with the database/makes a call using Facebook's API, 
//and populates the leaderboard table with the returned data
}

在开始新游戏时,玩家的当前排名存储在隐藏的div中。

游戏完成时, updateTable(); 再次运行,然后运行compareRanks();

compareRanks(){
//code here grabs the stored rank from the hidden div
//code here grabs the newly updated rank and compares the two.
}

我已经阅读了有关使用回调的答案,但无法使它们正常工作。 我尝试做这样的事情:

updateTable(){
{
//code here interacts with the database/makes a call using Facebook's API,
//and populates the leaderboard table with the returned data
}
compareRanks();
};

但是当compareRanks();时,新排名仍然与旧排名相同compareRanks(); 运行。 updateTable(); 运行时可以正确更改排行榜上的排名,因此我认为compareRanks(); updateTable();之前运行updateTable(); 完全完成。

非常感谢您为解决此问题提供的帮助,在此先感谢您!

解决此问题的一种好方法是使用Javascript Promises。 它们允许您执行异步操作,而无需嵌套多个回调函数。

function first (parameter){
  return new Promise(function(resolve,reject){
   //Do async stuff, maybe some ajax

   //When async stuff is finished:
    resolve(async_data);
   //Or when something went wrong:
    reject(error);
 }
}

function second(parameter){
  return new Promise(function(resolve,reject){
   //Do async stuff, maybe some ajax

   //When async stuff is finished:
    resolve(async_data);
   //Or when something went wrong:
    reject(error);
 }
}

//You can then use:
first(data).then(second(async_data)).then(function(async_data){
    //Here would be the point where both functions finished after eachother!
}).catch(function(error){
    //Hey, one of my promises was rejected! Maybe I should handle that error :)
});

这具有一些优点。 您可以根据需要在.then的链中放入任意数量的函数和操作.then而无需嵌套大量的回调函数。 您还可以通过使用.catch()来访问reject()调用。 您应该考虑阅读Promises的文档,因为还有更多有趣的功能。

如果您不希望参与Promises(因为它们是可组合的 ,它们使您的代码更加整洁,因此您可以创建非常清晰的Promise链),则可以研究其他一些与Callbacks一起使用的awns(不是那么糟糕)这么小的用例)。

这是一篇很棒的文章: 文章:JavaScript Promises

基本上,回调是作为参数传递给另一个函数的函数。 JavaScript能做到这一点,因为函数是一流的对象。

现在,由于updateTable将调用db / FB API,因此您需要该操作的回调中调用该回调。 我不知道该操作的正确语法,因此我的示例使用了伪代码。

function updateTable(callback) {
   FBAPI.get(something, function (data) {
     // do things
     callback();
   });
}

updateTable(compareRanks);

请注意,如果compareRanks需要从API访问数据,您也可以将数据传递给回调:

callback(data);

最好使用javascript-的new Promise对象

Promise对象用于延迟和异步计算。 Promise表示尚未完成的操作,但有望在将来进行。

new Promise(executor);

new Promise(function(resolve, reject) { ... });

检查此链接以获取更多帮助-https ://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise

我认为Aless80的评论是您回答问题的关键。 我不知道Facebook API的外观,但是每当您与数据库或Web服务器进行交互时,API调用通常都有一个回调,您可以在其中处理服务器可能返回给您的任何内容。

例如,我正在使用的简单Web服务器处理从浏览器通过AJAX调用发送的请求。 我正在使用Jquery来做到这一点,但是结构应该大致相同。

var dataObject = {};
var dataID = "1234";
$.ajax({
  type: "GET", // basic http get request
  url: "http://www.mywebserver.com/get-data/" + dataID,
  crossDomain: true 
}).done(function(response){
  // this function runs after the webserver has received our GET request and handled it
  // response contains the data we got back from mywebserver
  dataObject = response;
});
DoSomething(dataObject);

这里发生的是,在dataObject包含数据库返回的任何数据之前,将触发“ DoSomething()”! 因此,如果我们想对返回的数据做一些事情,我们应该在我们的ajax请求的“回调”中调用该函数,如下所示:

var dataObject = {};
var dataID = "1234";
$.ajax({
  type: "GET", // basic http get request
  url: "http://www.mywebserver.com/get-data/" + dataID,
  crossDomain: true 
}).done(function(response){
  //dataObject = response;
  //DoSomething(dataObject);
  DoSomething(response);
});

在本示例中,为使注释清楚起见,是为了清楚起见,当然,我们希望避免不必要地传递变量:)

我也强烈建议您研究JavaScript回调。 一开始很难理解它们,但是Node.js基本上是基于该概念构建的,因此非常值得熟悉它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM