Javascript 在循环内更新UI(在循环内使用等待函数)

Javascript 在循环内更新UI(在循环内使用等待函数),javascript,multithreading,loops,Javascript,Multithreading,Loops,在下面的javascript中,呈现了一个tic-tac-toe游戏: src: 正文{ 文本对齐:居中; 字体系列:Arial、Helvetica、无衬线字体; } 氢{ 保证金:0自动; 字体大小:35px; 利润率:10px; } .柔性容器{ /*为了使用flex box,我们需要首先设置display属性*/ 显示器:flex; /*使容器水平居中*/ 证明内容:中心; /*这将使内容垂直居中*/ 对齐项目:居中; /*告诉容器对齐列中的子项而不是行中的子项*/ } .柔性柱{ 身高:

在下面的javascript中,呈现了一个tic-tac-toe游戏:

src:

正文{
文本对齐:居中;
字体系列:Arial、Helvetica、无衬线字体;
}
氢{
保证金:0自动;
字体大小:35px;
利润率:10px;
}
.柔性容器{
/*为了使用flex box,我们需要首先设置display属性*/
显示器:flex;
/*使容器水平居中*/
证明内容:中心;
/*这将使内容垂直居中*/
对齐项目:居中;
/*告诉容器对齐列中的子项而不是行中的子项*/
}
.柔性柱{
身高:100%;
宽度:100%;
弯曲方向:立柱;
/*通知容器在达到最大宽度时放下*/
}
.柔性包装{
柔性包装:包装;
身高:432px;
宽度:432px;
}
.广场{
边框:2倍实心rgba(0,0,0,75);
高度:140像素;
宽度:140px;
字号:80px;
显示器:flex;
对齐项目:居中;
证明内容:中心;
}
#复位按钮{
文本对齐:居中;
字体大小:20px;
边框:1px纯黑;
高度:55px;
宽度:100px;
利润率:10px;
}
为人类的利益授权Tic-Tac-Toe
抽搐
轮到X了!
重置
/*-----常数-----*/
常量winningCombos=[
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
/*-----应用程序的状态(变量)-----*/
让董事会;
让我们转身='X';
让我们赢;
/*-----缓存的元素引用-----*/
const squares=Array.from(document.queryselectoral(“#board div”);
/*-----事件侦听器-----*/
document.getElementById('board')。addEventListener('click',handleTurn);
const messages=document.querySelector('h2');
document.getElementById('reset-button')。addEventListener('click',init);
/*-----功能-----*/
函数getWinner(){
设winner=null;
winningCombos.forEach(函数(组合,索引){
如果(board[combo[0]]和board[combo[0]]==board[combo[1]]和board[combo[0]]==board[combo[2]])赢家=board[combo[0]];
});
返回赢家?赢家:董事会。包括(“”)?空:“T”;
};
函数getPosition(playerName){
const userAction=async()=>{
const response=等待获取(“/”{
方法:“GET”,
正文:'/data/3',//字符串或对象
标题:{
“内容类型”:“应用程序/json”
}
});
const myJson=await response.json();//从http响应中提取json
log('myJson',myJson)
//用myJson做些什么
}
var client=新的HttpClient();
client.get('/data/3',函数(响应){
console.log('响应为'+响应)
});
console.log('为玩家获取位置'+玩家名称)
}
var HttpClient=function(){
this.get=函数(aUrl、aCallback){
var anHttpRequest=newxmlhttprequest();
anHttpRequest.onreadystatechange=函数(){
如果(anhtprequest.readyState==4&&anhtprequest.status==200)
aCallback(anhtprequest.responseText);
}
anhtprequest.open(“GET”,aUrl,true);
anHttpRequest.send(空);
}
}
函数handleTurn(){
设idx=squares.findIndex(函数(平方){
返回平方===event.target;
});
console.log('Turn is'+Turn)
如果(转动='X'){
getPosition('X')
线路板[idx]=匝数;
转动=转动=='X'?'O':'X';
}
否则{
getPosition('O')
线路板[idx]=匝数;
转动=转动=='X'?'O':'X';
}
win=getWinner();
render();
};
函数init(){
董事会=[
'', '', '',
'', '', '',
'', '', ''
];
render();
};
函数render(){
board.forEach(功能(标记、索引){
//这会将线路板项目的值移动到正方形[idx]
正方形[索引]。文本内容=标记;
});
messages.textContent=win=='T'?'这是一场平局,女王!`:win?`${win}赢了比赛!`:'轮到${turn}了!`;
};
函数等待(毫秒)
{
var d=新日期();
var d2=null;
do{d2=新日期();}
d2-d
我试图将“X”发送到所有位置,间隔1秒:

turn = 'X'
for (i = 0; i <= 8; i++) {
        board[i] = 'X';
        turn = turn === 'X' ? 'O' : 'X';
        console.log(board)
        render();
        wait(1000)
}
turn='X'

对于(i=0;i实际上,您在这里面临两个问题

  • 您不需要使用自定义等待函数,等待函数不是一个很好的实践,因为它会阻止您的执行运行时(因为javascript是单线程语言)因此,您的代码将消耗大量的资源。相反,您必须使用本机浏览器API函数,如,或,这将使您的代码异步,并防止阻塞代码

  • 循环不会等待自定义等待函数或甚至
    设置超时
    设置间隔
    完成
    ,它们将继续迭代到最后一个元素。因此您需要为每个循环设置不同的时间延迟,以便在不同的时间执行它们,然后用于保存
    i
    的值ng>。因此,为了做到这一点,您需要在每次迭代执行后精确地增加
    i
    值。因此,使用
    while
    loop over
    for
    循环的最佳实践。有关循环的更多信息,您可以阅读


  • 最后,为了使其工作,您应该替换

    turn='X'
    对于(i=0;i
    
    turn = 'X'
    for (i = 0; i <= 8; i++) {
            board[i] = 'X';
            turn = turn === 'X' ? 'O' : 'X';
            console.log(board)
            render();
            wait(1000)
    }