发布网友 发布时间:2024-09-06 17:20
共1个回答
热心网友 时间:2024-09-14 21:36
【前言】Node.js是一个异步事件驱动的JavaScript的运行环境,旨在建立可以扩展的网络应用,所谓异步事件是指JavaScript中的所有那些在后台处理的(例如Ajax请求)、而且不会阻塞任何其他请求的功能。这篇文章将帮助你学习并理解Node.js是如何工作的,如何处理发送到服务器的功能和请求,无论是同步还是异步。
什么是事件循环机制JavaScript被设计为单线程语言,也就是说每次只能执行一项任务,其他任务都得按照顺序排队等待被执行,只有当前的任务执行完成之后才会执行下一个任务。任务分为同步任务和异步任务,异步任务永远在同步任务执行完后才执行,而事件循环是一个事件*(event-listener),他在Node环境中发挥作用,并随时准备监听、处理和输出一个事件(event),而这个事件可以是任何东西。
什么是同步和异步同步编程同步编程(Synchronousprogramming)意味着代码按其定义的顺序运行。在一个同步程序中,当一个函数被调用并返回了一些值后,才会执行下一行。
代码举例
const?listItems?=?function(items)?{????items.forEach(function(item)?{????????console.log(item)????})};const?items?=?["Buy?milk",?"Buy?coffee"]listItems(items);输出结果
Buymilk
Buycoffee
在上述代码中,当listItems(items)函数被调用时,它将循环浏览数组中的项目。console.log(item)函数首先对数组的第一个项目被调用,并打印出"Buymilk",然后console.log(item)再次被执行,这次它通过数组的第二项,并打印出"Buycoffee",所以说这个函数是按照它被定义的顺序执行的,也称为同步执行。
异步编程异步编程(Asynchronousprogramming)是指不按顺序执行的代码。这些函数不是按照它们在程序中定义的顺序执行,而是只有在满足某些条件时才执行。
例如:setTimeOut()在延迟一定时间的毫秒后执行一项任务。代码举例
setTimeout(()?=>?{????console.log('我是一个异步任务');},?4000)const?listItems?=?function(items)?{????items.forEach(function(item)?{????????console.log(item)????})}const?items?=?["Buy?milk",?"Buy?coffee"]listItems(items);输出结果
Buymilk
Buycoffee
我是一个异步任务
在上述代码中,代码的执行顺序依旧从上到下,执行到setTimeout()函数时,发现是一个异步任务,并不会立即执行,而是继续向下执行同步代码,打印出Buymilk和Buycoffee,等待所有的同步任务都执行结束之后,返回执行setTimeout()函数,等待4秒后执行完毕打印出我是一个异步任务。
处理异步任务流程图
宏任务和微任务宏任务宏任务(macro)task,可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行);
宏任务举例:
任务(代码)宏任务环境script宏任务浏览器事件宏任务浏览器网络请求(Ajax)宏任务浏览器setTimeout()定时器宏任务浏览器/Nodefs.readFile()读取文件宏任务Node微任务微任务(microtask)是宏任务中的一个部分,它的执行时机是在同步代码执行之后,下一个宏任务执行之前。
微任务包含:
Promise.then;
process.nextTick(Node.js环境)。
运行机制在事件循环中,每进行一次循环操作称为tick,每一次tick的任务处理模型是比较复杂的,但关键步骤如下:
执行一个宏任务(执行栈中没有就从事件队列中获取);
执行过程中如果遇到微任务,就将它添加到微任务的任务队列中;
宏任务里的同步代码执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行);
当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染;
渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)。
【往期分享】
ES6中的Promise
Node.js安装使用
原文:https://juejin.cn/post/7097119422585765901