node异步API setTimeout,setInterval,process.nextTick,setImmediate详解

setTimeout

setTimeout是在指定时间间隔后将其插入到执行队列中,但是若他之前有运行时间较长的程序,则其执行时间可能比指定时间晚。

分析以下代码:

//part1:some code here,it may cost a lot time

var timer1 = setTimeout(function(){

    //part2:some code here,it may cost a lot time

    var timer2 = setTimeout(arguments.callee,1000);
},1000);

问:time1在1s后将其插入到执行队列,但是它是在1s后执行的吗?
答:是不一定,若part1执行时间超过1s则time1的执行时间比1s晚。

问:time2是在time1执行开始后1s执行的吗?
答:是不一定,若part2执行时间超过1s则不是。

setInterval

setInterval是在指定时间间隔后将定时器插入到执行队列中。但是定时器中的代码执行时间过长的话,两个定时器间隔可能变小,且有的定时器可能被越过。

分析以下代码:

var timer3 = setInterval(function(){
    //part3:some code here,it may cost a lot time
},1000);

part3的执行时间为3000,假设在1s后将第1个time3插入到执行队列,当part3运行到1000的时候,将第2个time3副本插入到执行队列,当part3运行到2000的时候,由于定时器队列中已经有1个定时器实例了,因此第3个time3副本将不会被插入到执行队列,当part3运行结束的时候,立即运行第2个time3副本,(此时第1个time3和第2个time3之间没有事件间隔),并在定时器队列中插入第4个time3副本。

实质上,setTimeout和setInterval会被插入到定时器观察值内部的红黑树中,而每次事件循环迭代从红黑数中取出定时器对象需要耗费性能,时间复杂度为O(logn),所以setTimeout(fn,0)较浪费性能;都返回一个唯一数值,表示计时器间隔,目的是取消计数时器。

process.nextTick

process.nextTick是将其插入到当前循环队列末尾.早于setTimeout(function(){},0);可以理解为setTimeout0是在下次循环开始,而process.nextTick结束后本次循环才完成,但是Promise.resolve()是在process.nextTick之后执行的。

setImmediate

setImmediate是真正将其插入到下次循环队列末尾。

new Promise(function () {
    console.log('promise');
});
Promise.resolve().then(function () {
    console.log('resolve');
});

setTimeout(function () {
    console.log('setTimeout')
}, 0);

setImmediate(function () {
    console.log('Immediate')
});

process.nextTick(function () {
    console.log('tick')
});
setInterval(function () {
   console.log('interval')
},0);
console.log('outer');

输出结果:

promise
outer
tick
resolve
setTimeout
interval
Immediate
interval
interval
interval

setTimeout和闭包题目


for(var i = 0; i<3; i++){
    setTimeout(
        say,
        (function () {
        var b =  i*1000;
        console.log(b);
        return b;
        })(),
        i
    );
}
function say(msg) {
    console.log('****** '+msg);
}

以上输出:

0
1000
2000
****** 0
****** 1
****** 2

因为setTimeout的第3个参数每次将当前的i传递给say方法。
而下面的执行结果中i保留的是最后的全局i

for(var i = 0; i<3; i++){
    setTimeout(
        function(){
            say(i);
        },
        (function () {
        var b =  i*1000;
        console.log(b);
        return b;
        })()
    );
}
function say(msg) {
    console.log('****** '+msg);
}

输出结果为:

0
1000
2000
****** 3
****** 3
****** 3

setTimeout的第一个参数在node环境下必须是函数,否则会出错,但是在浏览器端可以不是,下面成语在浏览器端执行:

for(var i = 0; i<3; i++){
    setTimeout(
        (function(a){
            say(a);
        })(i),
        (function () {
        var b =  i*1000;
        console.log(b);
        return b;
        })()
    );
}
function say(msg) {
    console.log('****** '+msg);
}

输出:
****** 0
0
****** 1
1000
****** 2
2000

可见当setTimeout第一个参数为立即执行函数时的确会立即执行,在解析的时候就执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
process.nextTick() 是 Node.js 中用于在事件循环的下一次迭代中调用回调函数的方法。它接受一个没有时间限制的回调函数作为参数,并将其安排在事件循环的下一次迭代中执行。与 setTimeout() 不同,process.nextTick() 的回调函数会在当前迭代结束后立即执行,而不是等待一定的时间间隔。这使得 process.nextTick() 比 setTimeout() 更快,因为它不需要等待定时器的时间到期。\[1\]\[2\] 在 Node.js 中,process.nextTick() 的使用场景包括但不限于以下几种情况: 1. 在当前操作完成后立即执行回调函数,以确保回调函数在下一次事件循环迭代中被调用。 2. 在事件循环的不同阶段之间切换执行上下文,以避免阻塞事件循环。 3. 在异步操作的回调函数中处理错误,以确保错误能够被捕获并进行适当的处理。 总之,process.nextTick() 是一种用于在事件循环的下一次迭代中调用回调函数的方法,它具有快速执行和灵活的使用场景。\[1\]\[2\] #### 引用[.reference_title] - *1* *2* [process.nextTick() 在 Node.js 中是如何工作的?](https://blog.csdn.net/weixin_46267040/article/details/125369737)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [详解 setTimeoutsetImmediateprocess.nextTick 的区别](https://blog.csdn.net/weixin_39489765/article/details/123235183)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值