本篇文章带大家了解一下Nodejs中的模块化和事件循环。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。
|
本篇文章带大家了解一下Nodejs中的模块化和事件循环。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。
5.20出了一款线上Ide,能够在浏览器上边运行 Node.js —WebContainers 1 Node.js简介Node.js 到底是什么?开始学习的时候,对于前端的一些知识领域没有太多的接触(当然现在也一样),对于 Node.js 的印象就是,它和Javascript 的语法几乎一样,然后是写后端的。记得当时还窃喜,学了 Javascript = 啥都会了!好了切入正题 以前 Javascript 都是运行在浏览器上边的,Javascript 是一种高级语言,计算机不能直接读懂,毕竟二进制的计算机的世界里边就只有010101...,在这个时候浏览器中的 JavaScript 引擎,就充当了翻译官的角色,把 JavaScript 想要做什么手把手翻译给计算机,这其中的编译过程就不细说(我暂时也说不清楚)。 Node.js 基于 Chrome 浏览器的 V8 引擎,可以高效的编译 Javascript,所以可以说 Node.js 是除浏览器以外的另一个 Javascript 运行环境。 记得在腾讯云的云函数上折腾过微信公众号的简单的自动回复,当时对前端代码的模块化有了小小的体会,Node.js 的功劳! 2 初体验server.js 文件如下 // 引入 http 模块
var http = require("http");
// 用 http 模块创建服务
//req 获取 url 信息 (request)
//res 浏览器返回响应信息 (response)
http.createServer(function (req, res) {
// 设置 HTTP 头部,状态码是 200,文件类型是 html,字符集是 utf8
//Content-Type字段用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,不写就可能会出现乱码哦
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
// 往页面打印值
res.write('小林别闹');
// 结束响应
res.end();
}).listen(3000); // 监听3000端口安装了 Node 的前提下在终端运行
此时我们在本地搭建起一个最简单的服务器,浏览器作为客户端进行访问 2.1 模块化在上边的代码中,我们注意到了有 2.1.1CommonJS提到模块化,就必须提一嘴 CommonJS,Node.js 就采用了部分 CommonJS 语法,可以理解为 CommonJS 是一种模块化的标准.在早期为了解决通过 在这里可以梳理一下导出 test2.js 如下: let str = require('./test1');
console.log(str)当 test1.js如下: let str1 = '小林别闹1' let str2 = '小林别闹2' exports.str1 = str1 exports.str2 = str2 console.log(module.exports === exports) 在终端执行 /*输出
{ str1: '小林别闹1', str2: '小林别闹2' }
true
*/
//改变test1.js文件变量暴露的方式
/*
exports.str1 = str1
module.exports = str2
console.log(module.exports === exports)
输出:
false
小林别闹2
*/
/*
exports.str1 = str1
module.exports.str2 = str2
console.log(module.exports === exports)
控制台输出:
true
{ str1: '小林别闹1', str2: '小林别闹2' }
*/可以进行一下总结: 在 Node 执行一个文件时,会给这个文件内生成一个 另外注意,使用 2.1.2 Es ModuleJavascript 也是在不断的发展进步,这不, 导出: export const str1 = '小林别闹1'
export const str2 = '小林别闹2'
export default {
fn() {},
msg: "小林别闹"
}导入: import { st1,str2,obj } from './test.js'注意 比较一下的话就是: CommonJs 可以动态加载语句,代码发生在运行时 Es Module 是静态的,不可以动态加载语句,只能声明在该文件的最顶部,代码发生在编译时 2.1.3 第三方模块在Node 中除了可以使用自己提供的核心模块,自定义模块,还可以使用第三方模块 这就需要提到 当然包管理工具还有 2.2 Node 的事件循环2.2.1 非阻塞I/OJava、PHP 或者 .NET 等服务端语言,会为每一个客户端的连接创建一个新的线程。Node 不会为每一个客户连接创建一个新的线程,而仅仅使用一个线程。 console.log('1')
setTimeout(() => {
console.log('2')
})
console.log('3')//输出132Javascript 的代码是从上到下一行行执行的,但是这里就不会阻塞,输出3,再输出2 2.2.2事件循环Node 的事件循环真的好久才弄懂一丢丢,看过很多博客,觉得理解 Node 的事件循环机制,结合代码及其运行结果来分析是最容易理解的。 libuv 库负责 Node API 的执行。它将不同的任务分配给不同的线程,形成一个 Event Loop(事件循环),以异步的方式将任务的执行结果返回给 V8 引擎。其中 libuv 引擎中的事件循环分为 6 个阶段,它们会按照顺序反复运行。每当进入某一个阶段的时候,都会从对应的回调队列中取出函数去执行。当队列为空或者执行的回调函数数量到达系统设定的阈值,就会进入下一阶段。 console.log('start')
setTimeout(() => {//定时器1
console.log('timer1')
setTimeout(function timeout () {//定时器2
console.log('timeout');
},0);
setImmediate(function immediate () {//定时器3
console.log('immediate');
});
Promise.resolve().then(function() {
console.log('promise1')
})
}, 0)
setTimeout(() => {//定时器4
console.log('timer2')
Promise.resolve().then(function() {
console.log('promise2')
})
}, 0)
Promise.resolve().then(function() {
console.log('promise3')
})
console.log('end')可以 Node 上边运行一下
timers 阶段:这个阶段执行timer(setTimeout、setInterval)的回调 I/O callbacks 阶段:处理一些上一轮循环中的少数未执行的 I/O 回调 idle, prepare 阶段:仅node内部使用 poll 阶段:获取新的I/O事件, 适当的条件下node将阻塞在这里 check 阶段:执行 setImmediate() 的回调 close callbacks 阶段:执行 socket 的 close 事件回调 理解:首先执行同步任务,所以会输出
2.2.3浏览器的事件循环浏览器和 Node 的事件循环是不一样的 打算用两张图和一段代码来解释浏览器的事件循环机制, console.log(1)
setTimeout(()=>{console.log(2)},1000)//宏任务1
async function fn(){
console.log(3)
setTimeout(()=>{console.log(4)},20)//宏任务2
//return Promise.reject()返回失败状态的,不会输出6,弄不清楚为啥
return Promise.resolve()
}
async function run(){
console.log(5)
await fn()
//console.log(6),
}
run()
//需要执行150ms左右
for(let i=0;i<90000000;i++){}
setTimeout(()=>{//宏任务3
console.log(7)
new Promise(resolve=>{
console.log(8)
resolve()
}).then(()=>{console.log(9)})
},0)
console.log(10)
// 1 5 3 10 4 7 8 9 2执行结果如(请忽略我的工具提示):
我们可以储备一些前置知识:JavaScript 是单线程的,任务可以分为同步任务和异步任务,像 浏览器的事件循环机制就是:先执行同步任务,同步任务执行完成,就执行任务队列里面的任务,那任务队列里面的任务是哪来的呢?异步任务准备好了就会放进任务队列,你可以理解为,在任务队列里边宏任务和微任务都存在这一个队列结构管着它们。先后的话,同步任务执行完成后,任务队列里有微任务,则将微任务执行完,再执行一个宏任务,执行了宏任务可能又产生了微任务,这是就需要再执行完微任务任务。你可以将同步任务看成宏任务,这样就可以理解为,每执行完一个宏任务都要清理一遍微任务。
上边代码解释如下:执行到第一行代码,输出 这里直接看一位大哥的博客可能更加容易理解,写不了那么好,哭,链接放在下面了。 写的不好,羞愧万分,会努力学习的!!! 更多编程相关知识,请访问:编程视频!! 以上就是聊聊Nodejs中的模块化和事件循环的详细内容,更多请关注模板之家(www.mb5.com.cn)其它相关文章! |
