事件循环的原因: js的本职工作是为了处理dom元素,因此不能是一个多线程的语言,例如这个操作删除了某个dom元素,而其他操作正在移动这个元素,会造成一些不可预见的问题,因此js从开始就是一个单线程语言。
所以对于一个代码块来说,js会优先处理其中的同步代码,那么异步代码应该怎么处理。 这里就涉及到了js的事件循环机制。当一个代码块遇到异步代码的时候,js会把异步的回调放到一个队列中,俗称任务队列。 当这部分的同步代码结束的时候,js会返回来处理任务队列的完成的异步函数。
setTimeout(() => {
console.log('setTimeout')
}, 0);
console.log(1)
针对上述代码,即使延时器的时间为0,但是由于先执行代码块中的同步代码,那么还是先打印1
1
setTimeout
我们除了setTimeout之外,还有promise会经常在工作中用到,那么promise既然是异步操作,他的代码顺序应该也是在后面了,我 们尝试一下
var promiseT = new Promise((resove, reject) => {
console.log('Promise')//直接执行
})
setTimeout(() => {
console.log('setTimeout')
}, 0);
console.log(1)
我们会发现,打印的是
Promise
1
setTimeout
这是因为对于promise来说构造函数是同步执行的,所以会立即打印console.log('Promise'),但是 Promise中的回调函数是异步的,
var promiseT = new Promise((resove, reject) => {
console.log('Promise')
resove('resove')
})
setTimeout(() => {
console.log('setTimeout')
}, 0);
console.log(1)
promiseT.then(res=>{
console.log(res)
})
打印结果
Promise
1
resove
setTimeout
为什么明明setTimeout在代码块的前面,promise在后面,却先打印promise的回调呢
这是因为在js中对异步的执行分优先级,即我们说的宏任务微任务,对于一个事件队列中的异步任务,js会优先处理微任务,这也是为什么promiseT在后面却先执行的原因,对于宏任务和微任务的不同,这里不做阐述
下一期我会写一下时间循环在vue nexttick中的实际应用。 有什么更好的理解或者我有错的地方,大家指出来谢谢