js的settimeout方法 settimeout函数用法( 五 )


process.nextTick()process.nextTick()是一个特殊的异步API,他不属于任何的Event Loop阶段 。事实上Node在遇到这个API时,Event Loop根本就不会继续进行,会马上停下来执行process.nextTick(),这个执行完后才会继续Event Loop 。我们写个例子来看下:
var fs = require('fs')fs.readFile(__filename, () => {setTimeout(() => {console.log('setTimeout');}, 0);setImmediate(() => {console.log('setImmediate');process.nextTick(() => {console.log('nextTick 2');});});process.nextTick(() => {console.log('nextTick 1');});});这段代码的打印如下:
我们还是来理一下流程:
我们代码基本都在readFile回调里面,他自己执行时,已经在poll阶段遇到setTimeout(fn, 0),其实是setTimeout(fn, 1),塞入后面的timers阶段遇到setImmediate,塞入后面的check阶段遇到nextTick,立马执行,输出’nextTick 1’到了check阶段,输出’setImmediate’,又遇到个nextTick,立马输出’nextTick 2’到了下个timers阶段,输出’setTimeout’
这种机制其实类似于我们前面讲的微任务,但是并不完全一样,比如同时有nextTick和Promise的时候,肯定是nextTick先执行,原因是nextTick的队列比Promise队列优先级更高 。来看个例子:
const promise = Promise.resolve()setImmediate(() => {console.log('setImmediate');});promise.then(()=>{console.log('promise')})process.nextTick(()=>{console.log('nextTick')})代码运行结果如下:
总结本文从异步基本概念出发一直讲到了浏览器和Node.js的Event Loop,现在我们再来总结一下:
JS所谓的“单线程”只是指主线程只有一个,并不是整个运行环境都是单线程JS的异步靠底层的多线程实现不同的异步API对应不同的实现线程异步线程与主线程通讯靠的是Event Loop异步线程完成任务后将其放入任务队列主线程不断轮询任务队列,拿出任务执行任务队列有宏任务队列和微任务队列的区别微任务队列的优先级更高,所有微任务处理完后才会处理宏任务Promise是微任务Node.js的Event Loop跟浏览器的Event Loop不一样,他是分阶段的setImmediate和setTimeout(fn, 0)哪个回调先执行,需要看他们本身在哪个阶段注册的,如果在定时器回调或者I/O回调里面,setImmediate肯定先执行 。如果在最外层或者setImmediate回调里面,哪个先执行取决于当时机器状况 。process.nextTick不在Event Loop的任何阶段,他是一个特殊API,他会立即执行,然后才会继续执行Event Loop


以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!

「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助: