共计 3648 个字符,预计需要花费 10 分钟才能阅读完成。
之前始终以传统后端的思维来写 nodejs 的代码,发现运行后果与我的同步思维形式不太一样,所以须要全面将 nodejs 学习一下。此学习笔记适宜后端同学学习 nodejs 的时候观看,前端大佬能够多多斧正。
环境变量
console.log(setTimeout);
console.log(setInterval);
console.log(setImmediate);
console.log(__filename); // 以后文件的全名
console.log(__dirname); //
console.log(process); // 过程信息,全局变量
process 就是以后运行环境变量的集合体。例如 process.argv 就是获取用户输出的参数
数学库
与 Java 一样,叫 Math
Math.random(); // 返回 0~1 的浮点数
模块标准之 exports 和 module.exports 的关系
须要解决的问题:
脚本变多时,须要手动治理加载程序
不同脚本之间逻辑调用,须要通过全局变量的形式去交换,例如:JQUERY。将输入放到全局变量中,而后由其余局部进行应用
没有 html 怎么办?
nodejs 中应用 CommonJs 模块标准,加载另一个 js,用 require 函数来获取即可。
// demo.js
console.log("-----------");
let lib = require('./lib');
console.log('---------',lib);
// lib.js
console.log('==========');
exports.hello = '++++++++++';
exports.word = '///////////////';
exports.add = function () {console.log('1111111111111')
};
能够看见,模块中定义模块输入的形式:默认会注入一个叫 export 的变量,在该变量上挂参数就相当于给以后被 require 对象外面附一个值。还能够挂函数,对象等,实践上就是在输入对象中加对象。所以在 exports 中咱们能够挂各种类型的构造
同时,对于 exports 来说,里面能够扭转模块外面的内容,是同一个援用。
// demo.js
console.log("-----------");
let lib = require('./lib');
lib.addd = '*******************';
console.log('---------',lib);
// lib.js
console.log('==========');
exports.hello = '++++++++++';
exports.word = '///////////////';
exports.add = function () {console.log('1111111111111')
};
setTimeout(()=>{console.log(exports)
},2000);
运行后果如下,能够看见批改了里面被 require 的对象,外面的 exports 对象也被批改了
特定地,如果心愿被 require 进去的不是一个对象,而是一个办法,或者变量啥的,能够应用 module.exports,然而会笼罩掉之前怼 exports 变量的批改。
// demo.js
console.log("-----------");
let lib = require('./lib');
console.log('---------',lib);
// lib.js
console.log('==========');
exports.hello = '++++++++++';
exports.word = '///////////////';
exports.add = function () {console.log('1111111111111')
};
module.exports = function dsa() {return '123'};
最终打印的后果为
能够看到后果中 exports 变量的值并没有被输入进去,失去这样的后果有两种可能性,第一是 module.exports 将 exports 对象给笼罩掉了,第二种是 module.exports 和 exports 在文件被 require 的时候其实是两个不同的货色,指向两个不同的内存,当模块被 require 的时候,如果 module.exports 没有被指定,那么就 require 进去的是 exports 对象,如果 module.exports 被指定了,那么就应用 module,exports。我比拟偏向于前面这种解释,上面来证实我的观点。
// demo.js
console.log("-----------");
let lib = require('./lib');
lib.addd = '*******************';
console.log('---------',lib);
// lib.js
console.log('==========');
exports.hello = '++++++++++';
exports.word = '///////////////';
exports.add = function () {console.log('1111111111111')
};
setTimeout(()=>{console.log(exports)
},2000);
module.exports = function dsa() {return '123'};
setTimeout(()=>{console.log(module.exports)
},2000);
运行后果为:
能够看到,在 demo.js 中给援用的 lib 新增了 addd 属性,最终是作用到了 module.exports 上,同时,exports 打印的后果与 module.exports 并不一样,阐明,module.exports 和 exports 不是一个对象,只是在一个模块被援用时,module.exports 的优先级要高于 exports。
获取控制台输出(规范输入输出)
process.stdin.on('data', (e) => {const x = e.toString().trim();
console.log(x);
} );
包管理工具
每个语言都有包管理工具,不过 nodejs 有个坑,就是 npm 有时候版本和 nodejs 不匹配,这个时候就会抛出一些莫名其妙的谬误。碰到这种状况,就只能去 npm 官网解决问题局部寻找后果了。
npm init
要应用 npm,须要自身就是一个 npm 目录,所以须要应用 npm init 来申明为 npm 包
package.json
dependencies:放在外面,npm install 时会被主动下载,申明以后 npm 包所有的依赖
装置卸载
npm install xxx
npm uninstall xxx
国内镜像
npm 是国外的镜像,能够应用淘宝的 npm 镜像,能够去 NPM 镜像查看相干的办法
值得注意的是,用 cnpm 的时候要加上 –save 指令,否则 dependencies 中不会加进去
npm search xxx
很多同学不晓得本人适宜用什么包,比方我想连贯 redis,该应用什么包呢?就能够应用 npm search redis 来寻找了,雷同的,docker search redis/composer search redis 等等都是这么玩的。
nodejs 架构
基于 V8 运行环境
事件驱动:非阻塞式的 IO 模型
内置模块
nodejs 官方网站文档页面 nodejs 官方网站文档中文页面
底层能力是怎么实现的
以 os 为例,在源码的 lib 文件中:internalBinding(‘os’) 在 src/node_os.cc 中再调用 v8 的能力
Event 模块实现观察者模式,进而使得两个对象进行传输
EventEmitter,process 继承与它,所以能够往上抛事件,也就是典型的观察者模式。底层的能力封装起来放到一个模块中,里面的模块拿到这个代码,通过事件的监听器,就能比拟不便的,晓得子模块外面产生的变动。
观察者模式,能够用来解决两个对象的交换问题。
其实这个办法也能够实现两个函数的先后执行,从而将代码过程化,我看到这个还是比拟兴奋的,这样我就能够解决原本具备先后执行程序的代码,因为 nodejs 的异步个性导致无奈实现的,能够利用这个模式实现
const EventEmitter = require('events').EventEmitter;
class X extends EventEmitter{constructor(){super();
setInterval(()=>{
this.emit('newlesson',{price:Math.random()*100
});
},3000)
}
}
const x = new X();
x.addListener('newlesson',(res)=>{console.log('buy!',res);
});
炒鸡辣鸡原创文章,转载请注明起源