如何仅在第一个功能完全完成后才 运行 第二个 Javascript 功能?
How to run second Javascript function only after first function fully completes?
我正在使用 HTML 和 Javascript 创建一个 Facebook 游戏,我刚刚构建了一个排行榜 table,其中列出了每个玩家的名字和 运行 k 号。此 table 填充了从 Facebook 的游戏得分 API 返回的数据。
这很完美,但我也想奖励玩家在 table 中提高他们的 运行k。
我打算这样做:
- 当游戏加载时,我 运行 调用了一个函数
updateTable();
,这个
用玩家的分数和 运行ks 填充排行榜
从对 Facebook 数据库的 API 调用中收到。
- 当玩家开始玩游戏时,我将他们的 运行k 副本存储在一个单独的隐藏 div.
中
- 当游戏结束时,如果玩家获得了新的高分,则
它被输入到数据库中。发生这种情况后,我 运行
updateTable();
再次更新排行榜。
- 然后我 运行 一个函数叫做
compareRanks();
,它比较
玩家的新 运行k 和我存储在隐藏 div. 中的 运行k
如果新的 运行king 比存储的 运行k 小,那么他们已经在排行榜上上升,他们每上升一个位置我就会奖励他们 100 个硬币。
例如:
玩家 A 开始游戏并获得第 5 名 运行(因此“5”存储在隐藏的 div 中)。
当玩家 A 完成游戏时,排行榜会更新,玩家 A 现在 运行 排名第二(因此玩家跳了 3 位)。
为了计算奖励应该是多少,我想从第二个变量中减去第一个变量 (5-2 = 3),玩家 A 超过了其他 3 名玩家,因此他们的奖励将是 3 x 100 金币。
我遇到的问题是,当我 运行 compareRanks();
时,新的 运行k 一直显示为与存储的 运行k 相同的数字, 尽管我知道玩家已经提高了他们的 运行k.
我很确定这是因为新的 运行k 在 updateTable();
与数据库完全交互之前被抓取了。我通过分离功能测试了这个,通过点击按钮使 compareRanks();
运行,当我这样做时,我完成了一个游戏,改进了我的 运行k,等了几个updateTable();
运行 秒后,然后单击按钮,两个 运行ks 显示不同,这是正确的。所以我认为 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
}
在新游戏开始时,玩家的当前 运行k 存储在隐藏的 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();
运行s 时,新的 运行k 仍然显示为与旧的 运行k 相同。 updateTable();
在 运行s 时正确地改变了排行榜上的 运行ks,所以我认为 compareRanks();
只是 运行ning 在 updateTable();
完全完成。
如果能帮助解决此问题,我将不胜感激,在此先感谢您!
回调基本上是作为参数传递给另一个函数的函数。 JavaScript 可以做到这一点,因为函数是 first-class 个对象。
现在,因为 updateTable
将调用 db/FB API,您需要在 该操作的回调中调用回调 。我不知道该操作的正确语法,所以我的示例使用伪代码。
function updateTable(callback) {
FBAPI.get(something, function (data) {
// do things
callback();
});
}
updateTable(compareRanks);
请注意,如果 compareRanks
需要访问 API 中的数据,您也可以将数据传递给回调:
callback(data);
解决这个问题的一个好方法是使用 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
链中,而无需嵌套大量回调函数。您还可以使用 .catch()
访问 reject()
调用。您应该考虑阅读 Promises 的文档,因为还有更多您应该感兴趣的功能。
如果您不想参与 Promises(它们使您的代码更清晰,因为它们 可组合 因此您可以创建非常清晰的承诺链)您可以查看其他一些与回调一起工作的 awnsers(对于这么小的用例来说还不错)。
这是一篇很棒的文章:Article: JavaScript Promises
最好使用 new Promise
对象 javascript-
The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected in the future.
new Promise(executor);
new Promise(function(resolve, reject) { ... });
检查此 link 以获得更多帮助-
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
我认为 Aless80 的评论是您回答的关键。我不知道 Facebook API 是什么样子,但每当你与数据库或网络服务器交互时, API 调用通常会有一个回调,你可以在其中处理任何事情服务器可能 return 给你。
例如,我正在处理的一个简单的网络服务器处理通过来自浏览器的 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);
这里发生的是 "DoSomething()" 将在 dataObject 包含任何由数据库 return 编辑的数据之前触发!因此,如果我们想对 returned 数据做一些事情,我们应该在 ajax 请求的 "callback" 中调用该函数,如下所示:
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 基本上是建立在概念之上的,因此非常值得熟悉它们。
我正在使用 HTML 和 Javascript 创建一个 Facebook 游戏,我刚刚构建了一个排行榜 table,其中列出了每个玩家的名字和 运行 k 号。此 table 填充了从 Facebook 的游戏得分 API 返回的数据。
这很完美,但我也想奖励玩家在 table 中提高他们的 运行k。
我打算这样做:
- 当游戏加载时,我 运行 调用了一个函数
updateTable();
,这个 用玩家的分数和 运行ks 填充排行榜 从对 Facebook 数据库的 API 调用中收到。 - 当玩家开始玩游戏时,我将他们的 运行k 副本存储在一个单独的隐藏 div. 中
- 当游戏结束时,如果玩家获得了新的高分,则
它被输入到数据库中。发生这种情况后,我 运行
updateTable();
再次更新排行榜。 - 然后我 运行 一个函数叫做
compareRanks();
,它比较 玩家的新 运行k 和我存储在隐藏 div. 中的 运行k
如果新的 运行king 比存储的 运行k 小,那么他们已经在排行榜上上升,他们每上升一个位置我就会奖励他们 100 个硬币。
例如:
玩家 A 开始游戏并获得第 5 名 运行(因此“5”存储在隐藏的 div 中)。 当玩家 A 完成游戏时,排行榜会更新,玩家 A 现在 运行 排名第二(因此玩家跳了 3 位)。
为了计算奖励应该是多少,我想从第二个变量中减去第一个变量 (5-2 = 3),玩家 A 超过了其他 3 名玩家,因此他们的奖励将是 3 x 100 金币。
我遇到的问题是,当我 运行 compareRanks();
时,新的 运行k 一直显示为与存储的 运行k 相同的数字, 尽管我知道玩家已经提高了他们的 运行k.
我很确定这是因为新的 运行k 在 updateTable();
与数据库完全交互之前被抓取了。我通过分离功能测试了这个,通过点击按钮使 compareRanks();
运行,当我这样做时,我完成了一个游戏,改进了我的 运行k,等了几个updateTable();
运行 秒后,然后单击按钮,两个 运行ks 显示不同,这是正确的。所以我认为 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
}
在新游戏开始时,玩家的当前 运行k 存储在隐藏的 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();
运行s 时,新的 运行k 仍然显示为与旧的 运行k 相同。 updateTable();
在 运行s 时正确地改变了排行榜上的 运行ks,所以我认为 compareRanks();
只是 运行ning 在 updateTable();
完全完成。
如果能帮助解决此问题,我将不胜感激,在此先感谢您!
回调基本上是作为参数传递给另一个函数的函数。 JavaScript 可以做到这一点,因为函数是 first-class 个对象。
现在,因为 updateTable
将调用 db/FB API,您需要在 该操作的回调中调用回调 。我不知道该操作的正确语法,所以我的示例使用伪代码。
function updateTable(callback) {
FBAPI.get(something, function (data) {
// do things
callback();
});
}
updateTable(compareRanks);
请注意,如果 compareRanks
需要访问 API 中的数据,您也可以将数据传递给回调:
callback(data);
解决这个问题的一个好方法是使用 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
链中,而无需嵌套大量回调函数。您还可以使用 .catch()
访问 reject()
调用。您应该考虑阅读 Promises 的文档,因为还有更多您应该感兴趣的功能。
如果您不想参与 Promises(它们使您的代码更清晰,因为它们 可组合 因此您可以创建非常清晰的承诺链)您可以查看其他一些与回调一起工作的 awnsers(对于这么小的用例来说还不错)。
这是一篇很棒的文章:Article: JavaScript Promises
最好使用 new Promise
对象 javascript-
The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected in the future.
new Promise(executor);
new Promise(function(resolve, reject) { ... });
检查此 link 以获得更多帮助- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
我认为 Aless80 的评论是您回答的关键。我不知道 Facebook API 是什么样子,但每当你与数据库或网络服务器交互时, API 调用通常会有一个回调,你可以在其中处理任何事情服务器可能 return 给你。
例如,我正在处理的一个简单的网络服务器处理通过来自浏览器的 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);
这里发生的是 "DoSomething()" 将在 dataObject 包含任何由数据库 return 编辑的数据之前触发!因此,如果我们想对 returned 数据做一些事情,我们应该在 ajax 请求的 "callback" 中调用该函数,如下所示:
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 基本上是建立在概念之上的,因此非常值得熟悉它们。