Javascript 等待setInterval()完成

Javascript 等待setInterval()完成,javascript,settimeout,setinterval,wait,Javascript,Settimeout,Setinterval,Wait,我想在我的Javascript代码中添加一个小骰子滚动效果。我认为一个好方法是使用setInterval()方法。我的想法是以下代码(仅用于测试): 这段代码运行得很好。 但是在我的主代码中,roleDice()函数返回一个值。现在我不知道我该怎么处理。。。我无法从setTimeout()返回。如果我在函数的末尾添加一个返回,返回值将提升为fast。有人有主意吗,我怎么能解决这个问题 编辑 嗯,好吧,我知道回调剂量,我想我知道它是如何工作的,但我仍然有问题。我认为这更像是一个“界面”问题。。。

我想在我的Javascript代码中添加一个小骰子滚动效果。我认为一个好方法是使用
setInterval()
方法。我的想法是以下代码(仅用于测试):

这段代码运行得很好。 但是在我的主代码中,
roleDice()
函数返回一个值。现在我不知道我该怎么处理。。。我无法从
setTimeout()
返回。如果我在函数的末尾添加一个返回,返回值将提升为fast。有人有主意吗,我怎么能解决这个问题

编辑 嗯,好吧,我知道回调剂量,我想我知道它是如何工作的,但我仍然有问题。我认为这更像是一个“界面”问题。。。 这是我的代码:

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);
}
函数startAnimation(playername,回调){
变量i=数学地板((数学随机()*25)+5);
var int=setInterval(函数(){
我--;
变量编号=数学楼层((数学随机()*6)+1);
document.getElementById(“dice”).src=“./images/dice/dice”+number+“.png”;
if(i<1){
清除间隔(int);
数字=数学楼层((数学随机()*6)+1);
addText(playername+“rolled”+数字);
document.getElementById(“dice”).src=“./images/dice/dice”+number+“.png”;
回拨(号码);
}
}, 50);
}
功能rnd(播放器名称){
var callback=函数(值){
返回值;//我知道这是毫无意义的。。。
};
startAnimation(playername,回调);
}

函数
rnd()
应该等待并返回值…我有点困惑。目前我不知道该怎么做。。。代码等待
var回调…
,但我如何将其与返回结合起来呢?我想运行动画,然后用
rnd()
将最后一个数字返回到另一个函数。

大多数人在接触异步编程时都会遇到一个陷阱

您不能“等待”超时/间隔完成-尝试这样做将无法工作或阻止整个页面/浏览器。延迟后应该运行的任何代码都需要在“完成”时从传递给
setInterval
的回调调用


最初你的代码都是顺序的。这是一个基本的骰子游戏,两个玩家掷一个骰子,然后看谁的数字更大。[如果平局,第二人获胜!]

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();
函数角色指令(回调){
变量i=数学地板((数学随机()*25)+5);
var j=i;
var test=setInterval(函数(){
我--;
var die=Math.floor((Math.random()*6)+1);
document.getElementById(“dice”).src=“./images/dice/dice”+die+“.png”;
if(i<1){
清除间隔(试验);
回调(die);//将die值返回给函数以处理它
}
}, 50);
}
函数游戏(){
var gameInfo={//默认值
“p1”:空,
“p2”:空
},
playerRolls=函数(playerNumber){//开始滚动
var callbackpnc=函数(值){//创建一个将
playerFinishs(playerNumber,值);
};
roleDice(callbacknc);
},
playerFinishs=函数(playerNumber,value){//通过角色骰子触发的回调调用
gameInfo[“p”+玩家编号]=值;
如果(gameInfo.p1!==null&&gameInfo.p2!==null){//检查两个掷骰是否都已完成,如果已完成,则完成游戏
给定结果();
}
},
giveResult=function(){//在两次滚动完成时调用
var p1Win=gameInfo.p1>gameInfo.p2;
警报(“玩家”+(p1Win?:1:“2”)+“胜利!”);
};            
playerRolls(“1”);//启动播放器1
playerRolls(“2”);//启动播放器2
}
游戏();

以上代码在OOP类型的方式上可能更好,但它可以工作。

以上解决方案存在一些问题。运行该程序不会(至少在我的首选浏览器中不会)显示任何图像,因此必须在运行游戏之前加载这些图像

另外,根据经验,我发现在预加载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>

var游戏=功能(图像){
变量nbPlayers=2,winnerValue=-1,winnerPlayer=-1;
var rollDice=函数(玩家,调用回填){
var playerDice=document.getElementById(“骰子”+玩家);
var facesToShow=Math.floor((Math.random()*25)+5);
var intervalID=setInterval(函数(){
var face=Math.floor(Math.random()*6);
playerDice.src=images[face].src;
如果(--facesToShowwinnerValue){winnerValue=face;winnerPlayer=player}
如果(--nbplayers,您现在可以使用承诺
与回调一样,您可以使用承诺传递在程序运行完成时调用的函数。如果使用
拒绝
,您还可以使用承诺处理错误

函数rollDice(){
返回新承诺((解决、拒绝)=>{
const dice=document.getElementById('dice');
让numberOfRollsLeft=Math.floor(Math.random()*25+5);
const intervalId=setInterval(()=>{
const diceValue=Math.floor(Math.random()*6+1);
//显示新值的骰子面
dice.src=`./images/dice/dice${diceValue}.png`;
//如果我们完成了,停止滚动并返回骰子的值
如果(--numberOfRollsLeft<1){
rollDice(function(value) {
    // code that should run when the dice has been rolled
});
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();
<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>