![](/img/trans.png)
[英]How to run second function after the first has ended in javaScript?
[英]How to run second Javascript function only after first function fully completes?
我正在使用HTML和Javascript创建一个Facebook游戏,并且我刚刚完成了一个排行榜表,该表列出了每个玩家的姓名和排名。 该表填充了从Facebook游戏分数API返回的数据。
这是完美的工作方式,但我也想奖励提高他们在表中排名的球员。
我打算这样做:
updateTable();
的函数updateTable();
,则使用从对Facebook数据库的API调用中接收到的球员的得分和排名来填充排行榜。 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.