Example-01
setTimeout(function () {
console.log("setTimeout");
});
setImmediate(function () {
console.log("setImmediate");
});
执行结果:
或
执行结果:setTimeout setImmediate / setImmediate setTimeout
注意点:在NodeJs中指定的延迟时间是有一定的误差的,所以导致了输出结果随机的问题; 解析: (setTimeout会被放在timers队列中,setImmediate会被放在check队列中) 情况一:NodeJS中首先会去到timers队列执行所有任务,如果setTimeout函数中的延迟时间推迟了,那么此时timers队列中是没有满足条件的异步任务的,那么js线程就会检查有没有微任务,如果没有,继续来到poll队列,poll队列中没有异步任务,再去检查有没有微任务,如果没有继续往下执行,来到check队列,就会执行setImmediate任务,接着,又去检查有没有微任务,如果没有,再去检查timers队列,进行刚刚的重复操作,这种情况下执行结果就是setImmediate setTimeout; 情况二:如果setTimeout函数中的延迟时间没有推迟或者是提前了,那么此时timers队列中是有满足条件的异步任务的,那么js线程直接执行当前任务,接着就会检查有没有微任务,如果没有,继续来到poll队列,poll队列中没有异步任务,再去检查有没有微任务,如果没有继续往下执行,来到check队列,就会执行setImmediate任务,接着,又去检查有没有微任务,如果没有,再去检查timers队列,进行刚刚的重复操作,这种情况下执行结果就是setTimeout setImmediate ;
Example-02
const path = require("path");
const fs = require("fs");
let filePath = path.join(__dirname,"02-a.js");
fs.readFile(filePath,function () {
setTimeout(function () {
console.log("setTimeout");
});
setImmediate(function () {
console.log("setImmediate");
});
});
执行结果:
解析:因为读取文件操作属于I/O操作,所以readFile这个异步任务会放在poll队列中,首先来到timers队列,再来到poll队列,执行readFile代码,把setTimeout异步任务会放在timers队列中,把setImmediate异步任务会放在check队列中,此时poll队列执行完毕,会去检查有没有微任务,如果没有,会切换到check队列中,所以会先执行setImmediate异步任务,接下来会切换到timers队列,执行setTimeout异步任务,所以,无论setImmediate写在前面还是后面,都会先执行setImmediate;