我想小骰子滚动效果添加到我的Javascript代码。 我认为一个好的办法是使用setInterval()
方法。 我的想法是以下(只是用于测试)的代码:
function roleDice() {
var i = Math.floor((Math.random() * 25) + 5);
var j = i;
var test = setInterval(function(){
i--;
document.getElementById("dice").src = "./images/dice/dice" + Math.floor((Math.random() * 6) + 1) + ".png";
if(i < 1) {
clearInterval(test);
}
}, 50);
}
现在,我想等待的setInterval,直到它完成。 所以我增加了一个setTimeout的。
setTimeout(function(){alert("test")}, (j + 1) * 50);
此代码的工作非常好。 但是,在我的主要代码roleDice()
函数返回一个值。 现在我不知道我怎么能搞定......我不能从返回setTimeout()
如果我添加一个返回函数结束时,回报率将提高到快。 有没有人有一个想法,我怎么能解决呢?
编辑嗯,好吧,我明白了什么回调剂量,我想我知道它是如何工作,但我还是有这个问题。 我认为这更是一个“接口”的问题......在这里我的代码:
function startAnimation(playername, callback) {
var i = Math.floor((Math.random() * 25) + 5);
var int = setInterval(function() {
i--;
var number = Math.floor((Math.random() * 6) + 1);
document.getElementById("dice").src = "./images/dice/dice" + number + ".png";
if(i < 1) {
clearInterval(int);
number = Math.floor((Math.random() * 6) + 1);
addText(playername + " rolled " + number);
document.getElementById("dice").src = "./images/dice/dice" + number + ".png";
callback(number);
}
}, 50);
}
function rnd(playername) {
var callback = function(value){
return value; // I knew thats pointless...
};
startAnimation(playername, callback);
}
函数rnd()
应该等待和返回值...我有点困惑。 目前,我不知道怎么回事...该代码等待的var callback...
但我可以如何与回报相结合呢? 我想运行的动画,并与后返回的最后一个数字rnd()
的其他功能。
Answer 1:
你迷迷糊糊进入陷阱大多数人在某些时候打,当他们与异步编程取得联系。
你不能“等待”的超时/间隔来完成 - 试图这样做是行不通或阻止整个页面/浏览器。 需要从您传递给回调叫应的延迟之后运行任何代码setInterval
时,它的“完成”。
function rollDice(callback) {
var i = Math.floor((Math.random() * 25) + 5);
var j = i;
var test = setInterval(function() {
i--;
var value = Math.floor((Math.random() * 6) + 1);
document.getElementById("dice").src = "./images/dice/dice" + value + ".png";
if(i < 1) {
clearInterval(test);
callback(value);
}
}, 50);
}
然后,使用这样的:
rollDice(function(value) {
// code that should run when the dice has been rolled
});
Answer 2:
UPDATE上TheifMaster的答案:
您现在可以使用的承诺
像回调,您可以使用承诺通过一个程序完成运行时,如果使用时被调用函数reject
你也可以承诺处理错误。
function rollDice() {
return new Promise((resolve, reject) => {
const dice = document.getElementById("dice")
let i = Math.floor((Math.random() * 25) + 5)
const intervalId = setInterval(() => {
const diceValue = Math.floor((Math.random() * 6) + 1)
dice.src = `./images/dice/dice${diceValue}.png`
if (--i < 1) {
clearInterval(intervalId)
resolve(diceValue)
}
}, 50)
})
}
然后使用它是这样的:
rollDice().then(value => alert(`Dice rolled: ${value}`))
Answer 3:
Orginally你的代码是所有顺序。 这是一个基本的骰子游戏,两个玩家推出一个和他们见谁拥有一个更大的数字。 [如果平局,第二夺人!]
function roleDice() {
return Math.floor(Math.random() * 6) + 1;
}
function game(){
var player1 = roleDice(),
player2 = roleDice(),
p1Win = player1 > player2;
alert( "Player " + (p1Win ? "1":"2") + " wins!" );
}
game();
上面的代码是非常简单的,因为它只是流。 当你把这样的摇动骰子一个异步方法,你需要的东西分解成块做处理。
function roleDice(callback) {
var i = Math.floor((Math.random() * 25) + 5);
var j = i;
var test = setInterval(function(){
i--;
var die = Math.floor((Math.random() * 6) + 1);
document.getElementById("dice").src = "./images/dice/dice" + die + ".png";
if(i < 1) {
clearInterval(test);
callback(die); //Return the die value back to a function to process it
}
}, 50);
}
function game(){
var gameInfo = { //defaults
"p1" : null,
"p2" : null
},
playerRolls = function (playerNumber) { //Start off the rolling
var callbackFnc = function(value){ //Create a callback that will
playerFinishes(playerNumber, value);
};
roleDice( callbackFnc );
},
playerFinishes = function (playerNumber, value) { //called via the callback that role dice fires
gameInfo["p" + playerNumber] = value;
if (gameInfo.p1 !== null && gameInfo.p2 !== null ) { //checks to see if both rolls were completed, if so finish game
giveResult();
}
},
giveResult = function(){ //called when both rolls are done
var p1Win = gameInfo.p1 > gameInfo.p2;
alert( "Player " + (p1Win ? "1":"2") + " wins!" );
};
playerRolls("1"); //start player 1
playerRolls("2"); //start player 2
}
game();
上面的代码可以在更多的面向对象类型的方式更好,但它的工作原理。
Answer 4:
有对上述解决方案工作的几个问题。 运行程序没有(至少在我的首选浏览器)显示任何图像,因此这些具有运行游戏之前加载。
此外,通过经验,我发现启动回调方法的情况下,像堆载预压N幅图像或具有N球员的最佳方式抛出骰子是让每超时功能做一个倒计时为零,在这一点上执行回调。 这就像一个魅力和不依赖于有多少项目需要处理。
<html><head><script>
var game = function(images){
var nbPlayers = 2, winnerValue = -1, winnerPlayer = -1;
var rollDice = function(player,callbackFinish){
var playerDice = document.getElementById("dice"+player);
var facesToShow = Math.floor((Math.random() * 25) + 5);
var intervalID = setInterval(function(){
var face = Math.floor(Math.random() * 6);
playerDice.src = images[face].src;
if (--facesToShow<=0) {
clearInterval(intervalID);
if (face>winnerValue){winnerValue=face;winnerPlayer=player}
if (--nbPlayers<=0) finish();
}
}, 50);
}
var finish = function(){
alert("Player "+winnerPlayer+" wins!");
}
setTimeout(function(){rollDice(0)},10);
setTimeout(function(){rollDice(1)},10);
}
var preloadImages = function(images,callback){
var preloads = [], imagesToLoad = images.length;
for (var i=0;i<images.length;++i){
var img=new Image();
preloads.push(img);
img.onload=function(){if(--imagesToLoad<=0)callback(preloads)}
img.src = images[i];
}
}
preloadImages(["dice1.png","dice2.png","dice3.png","dice4.png","dice5.png","dice6.png"],game);
</script></head><body>
<img src="" id="dice0" /><img src="" id="dice1" /></body></html>
文章来源: Wait until setInterval() is done