Javascript异步机制

Javascript做为一种单线程语言,是如何实现异步编程的呢?javascript

相信很多人对Javascript单线程表示怀疑:为什么单线程能够实现异步操做呢?其实Javascript确实是单线程的(咱们不妨把这个线程称做主线程),但它实现异步操做的方式确实借助了浏览器的其余线程的帮助。那其余线程是怎么帮助Javascript主线程来实现异步的呢?答案就是任务队列(task queue)和事件循环(event loop)。java

任务队列

首先,做为单线程语言,在Javascript中定义的任务都会在主线程中执行。可是并非每一个任务都会马上执行,而这种不马上执行的任务咱们称做异步任务。相反,那些马上执行的任务咱们把它们称做同步任务。而这些异步任务都会交给浏览器的其余线程去执行,可是主线程须要了解这些异步任务执行的状态,才方便进行下一步操做。编程

打个比方,主线程准备作饭,因此下达一个异步任务去买菜,异步任务买完菜以后得告诉主线程:“我买完菜啦”,这个时候主线程才好开始作饭。浏览器

而咱们知道由于Javascript是单线程,因此上述的“下一步操做”无法直接定义在主函数里(否则就被当作同步任务直接执行了),那这些应该定义在哪里呢?答案就是异步任务的回调函数中。在Javascript异步机制中,任务队列就是用来维护异步任务回调函数的队列。这样一个队列用来存放这些回调函数,它们会等到主线程执行完全部的同步函数以后按照先进先出的方式挨个执行。那么执行完任务队列以后呢?Javascript主线程就执行完毕了吗?固然不是,否则网页加载完毕以后,谁来处理后续与用户的交互事件(好比点击事件)呢?异步

事件循环

javascript_asyc.jpg
咱们经过上图来更加形象的了解Javascript的异步机制。
执行同步任务 -> 检查任务队列中是否有任务 -> [有若是则执行] -> 检查任务队列中是否有任务 -> [有若是则执行] -> ......
可见主线程在执行完同步任务以后,会无限循环地去检查任务队列中是否有新的“任务”,若是有则执行。而这些任务包括咱们在异步任务中定义的回调函数,也包括用户交互事件的回调函数。经过事件循环,Javascript不只很好的处理了异步任务,也很好的完成了与用户交互事件的处理。由于在完成异步任务的回调函数以后,任务队列中的任务都是由事件所产生的,所以咱们也把上述的循环过程叫作事件循环异步编程

异步机制实践

console.log('定时器去买菜吧')
setTimeout(function(){
    console.log('菜买完了,主线程去作菜吧')
}, 0)
console.log('你先去买菜,我先看个世界杯')

在浏览器中执行上述代码,兴许能更好地理解Javascript的异步机制。函数

总结

总而言之,Javascript单线程的背后有浏览器的其余线程为其完成异步服务,这些异步任务为了和主线程通讯,经过将回调函数推入到任务队列等待执行。主线程所作的就是执行完同步任务后,经过事件循环,不断地检查并执行任务队列中回调函数。oop

相关文章
相关标签/搜索