JS 定时器 setInterval() 和 setTimeout() 面试题:定时器传参和返回值,异步任务

    技术2023-03-27  99

    题目如下, fn1() 和 fn2() 结果?

    function fn1() { for (var i = 0; i < 4; i++) { var tc = setTimeout(function (i) { console.log(i); clearTimeout(tc); },10, i) } } function fn2() { for (var i = 0; i < 4; i++) { var tc = setInterval(function (i, tc) { console.log(i); clearInterval(tc); }, 10, i, tc) } } fn1(); fn2();

    答案:

    fn1(); // 0,1,2 fn2(); // 0,1,2,3,3,3,3,3.....

    解析:

    function fn1() { for (var i = 0; i < 4; i++) { var tc = setTimeout(function (i) { // var 变量回被提升,变量值会被后面覆盖 console.log(i); // 打印定时器被传进来的参数i clearTimeout(tc); // tc变量最后的值是最后一个定时器的ID: 4 },10, i) // i 的传参会一直被保留,知道定时器启动时被调用 } } function fn2() { for (var i = 0; i < 4; i++) { var tc = setInterval(function (i, tc) { console.log(i); // 打印定时器被传进来的参数i clearInterval(tc); // 这里的 tc 是每次被传进来的定时器的ID }, 10, i, tc) // 传参的 i, 和定时器ID值 tc 会被保留 } }

    这道题涉及定时器的传参和返回值,以及JS执行顺序异步问题。

    定时器语法:
    var intervalID = scope.setInterval(func, delay, [arg1, arg2, ...]) var timeoutID = scope.setTimeout(function[, delay, arg1, arg2, ...])

    第一个参数func是执行函数,第二个参数 delay 是延迟时间, 后面的参数都是传给执行函数的参数。

    定时器的返回值是定时器的计数器,从1开始计数,表示定时器的ID, 这个ID 传递给 clearInterval() 和 clearTimeout() 来清除定时器。注意,intervalID 和 timeoutID 会公用一个编号池。

    异步任务:

    定时器在JS中被作为异步任务,放到任务队列中,当主线程任务执行完之后,会来执行异步任务。

    两个函数的执行过程:

    fn1函数:

    fn2函数:

    Processed: 0.021, SQL: 10