猿问

js中如何让setInterval倒计时中的alert顺序执行?

关键代码如下:


var sec = 10;

var t = setInterval(function(){

    sec--;

    $(".time").html(sec);

    if(sec == 0){

        alert("游戏结束,你的得分是" + score);

        clearInterval(t);

    }

},1000)

当倒计时到最后1秒的时候,会先弹出对话框,此时页面上显示的时间还是1s,等点击确定后才会变成0。

我想要的效果是页面上显示倒计时为0的时候显示弹出,而且点击确定后时间不会变成-1,请问怎么实现呢?


慕尼黑的夜晚无繁华
浏览 718回答 2
2回答

临摹微笑

  var sec = 3;    var t = setInterval(function() {        sec--;        $(".time").html(sec);        if (sec == 0) {            setTimeout(function() {                alert("游戏结束,你的得分是" /*+ score*/ )            }, 0);            clearInterval(t);        }    }, 1000);分析:这个代码改不难,但是涉及到两个知识点,题主需要了解下,1、 修改 innerHTML 与 页面渲染的问题题主以为 alert() 先于 innerHTML 执行了,实际上不是的,执行顺序还是从上往下的,先修改的 DOM 元素的 innerHTML ,然后执行的 alert(),只不过 DOM 元素的 innerHTML 虽然改了,但是页面的渲染并没有进行,因为 js 是单线程的,只有所有的代码执行完了之后,有空闲,才会去渲染页面,实际上题主前面页面的渲染都是在 if 语句执行完后,主线程出现了空闲才进行的。咱们改个代码,看得更清楚些:    var sec = 3;    var score = 100;    var t = setInterval(function() {        sec--;        $(".time").html(sec);        alert("游戏结束,你的得分是" + score);        if (sec == 0) {            clearInterval(t);        }    }, 1000);这里每回都会更新页面和alert(),代码上先修改的 html,再 alert,但是实际运行的时候,你会发现,是先 alert 再渲染的 html; 所以题主产生了错觉,innerHTML 延后执行了;总结:DOM修改是同步的,但是页面的渲染要等主线程空闲;2、 定时器的**工作机制**除了主JavaScript 执行进程外,还有一个需要在进程下一次空闲时执行的代码队列;定时器对队列的工作方式是,当特定时间过去后将代码插入。注意,给队列添加代码并不意味着对它立刻执行,而只能表示它会尽快执行;如果在这个时间点上,队列中没有其他东西,那么这段代码就会被执行;在答案里,setTimout(fn,0)仅仅是立马把 fn 添加到了任务队列里,并没有马上执行。考虑两处代码:setTimeout('alert(1)',0);alert(2);alert(3);此时的主线程和任务队列:队列里的代码等主线程空闲时才会执行,所以 alert(1),会等到alert(2),alert(3)执行完毕后再执行;alert(1);alert(2);alert(3);此时的主线程和任务队列:所以代码按照从上往下的顺序正常执行;猜测,主线程在执行完代码后,会立马进行渲染,然后再执行任务队列里的代码,既然是队列,代码执行就是从第一个开始到最后一个结束。所以等代码执行完毕主线程空闲时,首先执行的是渲染,然后执行的 alert();总结:setTimout 是在指定间隔后,将代码加入任务队列里,等主线程空闲,执行渲染,再依次执行队列里的代码;所以最前面的代码加上 setTimeout 的作用就在于把代码移到队列里去了,等主线程空闲,页面渲染,再执行 alert();    var sec = 3;    var t = setInterval(function() {        sec--;        $(".time").html(sec);        if (sec == 0) {            setTimeout(function() {                alert("游戏结束,你的得分是" /*+ score*/ )            }, 0);            clearInterval(t);        }    }, 1000);参考资料:Is innerHTML asynchronous?When does InnerHTML execute immediately?How to detect when innerHTML is complete JavaScript 运行机制详解:再谈Event Loop

吃鸡游戏

    var sec = 3;     var score = 100;    var t = setInterval(function(){        sec--;        $(".time").html(sec);        if(sec == 0){          setTimeout(function(){            alert("游戏结束,你的得分是" + score);          },0)          clearInterval(t);        }    },1000)
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答