我正在使用HTML和Javascript创建一个Facebook游戏,我刚刚完成了一个排行榜表,其中列出了每个玩家的姓名和排名。此表填充了Facebook的游戏分数API返回的数据。
这是完美的,但我也想奖励玩家提高他们的排名。
我打算这样做:
updateTable();
的函数,这个
用排名和排名的玩家填充排行榜
通过API调用Facebook的数据库获得。updateTable();
再次更新排行榜。compareRanks();
的函数,这比较了。{
玩家的新排名,我已经存储在隐藏的div中。如果新排名的数字低于存储的排名,那么他们就会向排行榜上移,我会奖励每个排名上升的100个硬币。
例如:
玩家A开始游戏并排名第5(所以“5”存储在隐藏的div中)。 当玩家A完成游戏时,排行榜会更新,玩家A现在排名第2(因此玩家已经跳了3个位置)。
要算出奖励应该是什么,我想从第二个变量中减去第一个变量(5-2 = 3),玩家A超过其他3个玩家,所以他们的奖励将是3 x 100金币。
我遇到的问题是,当我运行compareRanks();
时,新排名会一直显示为与存储排名相同的数字,即使我知道玩家已经提高了排名。
我很确定这是因为在updateTable();
与数据库完全交互之前抓住了新排名。我已经通过分离函数测试了这个,通过单击按钮运行compareRanks();
,当我这样做时,我完成了一个游戏,提高了我的等级,在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();
运行时,新排名仍然与旧排名相同。 updateTable();
正在排行榜上正确更改排名,因此我认为compareRanks();
只是在updateTable();
完全完成之前运行。
我非常感谢你解决这个问题的任何帮助,谢谢你提前!
答案 0 :(得分:3)
接近这个的一个好方法是使用Javascript Promises。它们允许您在不嵌套多个回调函数的情况下执行异步操作。
$body = new stdClass();
$body->comment = "Check out https://github.com/faisalahsan";
$body->content = new stdClass();
$body->content->title = "Test ABCasdfadsf";
$body->content->description = "My Open Source Contribution";
$body->content->{'submitted-url'} = "https://github.com/faisalahsan";
$body->content->{'submitted-image-url'} = "https://avatars0.githubusercontent.com/u/8427383?v=3&s=460";
$body->visibility = new stdClass();
$body->visibility->code = "anyone";
$body_json = json_encode($body, true);
$client = new GuzzleHttp\Client(['base_uri' => 'https://api.linkedin.com']);
$access_token = 'AQWJ0bPoW9VpPrEYWvywLk2cx1fhwysjaadsfjja#fsExHBIJvTUGa_t_3FvaqZPnrsMACC-JyPvpL2GBANlOMLUBSK8OEyfUl9_VLoxVe4ACBePysj-_WHv1-PP-Q-xas2owrngUtlq9P7Z2o95XUiO-Xhd9y0bm36DX9JXyxW-3jV2uBwP9pLJDC_FRZQ2JiCE';
$req = $client->request('POST', '/v1/people/~/shares?format=json', [
'headers' => ["Authorization" => "Bearer " . $access_token,
"Content-Type" => "application/json",
"x-li-format"=>"json"],
'client_id' => '77gasdfkjo22v44',
'client_secret' => 'iXadQ123askdfzPbz7Js',
'body' => $body_json
]);
var_dump($req);
die;
这带来了一些优点。您可以将任意数量的函数和操作放入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
访问reject()
来电。你应该阅读Promises的文档,因为还有更多的功能应该对你有用。
如果您不想参与Promises(它们使您的代码更加清晰,因为它们可组合,因此您可以创建非常清晰的承诺链),您可以查看一些其他使用Callbacks的芒果(对于这么小的用例来说并不坏)。
以下是一篇很棒的文章:Article: JavaScript Promises
答案 1 :(得分:2)
回调基本上是一个函数作为参数传递给另一个函数。 JavaScript可以这样做,因为函数是第一类对象。
现在,因为updateTable
将调用db / FB API,所以需要在中调用该操作的回调中的回调。我不知道该操作的正确语法,所以我的示例使用伪代码。
function updateTable(callback) {
FBAPI.get(something, function (data) {
// do things
callback();
});
}
updateTable(compareRanks);
注意,如果compareRanks
需要访问API中的数据,您也会将数据传递给回调:
callback(data);
答案 2 :(得分:1)
最好使用javascript- {/ p>的new Promise
对象
Promise对象用于延迟和异步计算。承诺代表了一项尚未完成的行动,但预计将来会有所作为。
new Promise(executor);
new Promise(function(resolve, reject) { ... });
查看此链接以获取更多帮助 - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
答案 3 :(得分:1)
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);
这里发生的是" DoSomething()"将在dataObject包含数据库返回的任何数据之前触发!因此,如果我们想对返回的数据做一些事情,我们应该在"回调"中调用函数。我们的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基本上都是基于这个概念,所以非常值得熟悉它们。