美文网首页
传统后端开发者视角学习异步Nodejs的血泪笔记

传统后端开发者视角学习异步Nodejs的血泪笔记

作者: chaojilaji | 来源:发表于2020-10-21 11:39 被阅读0次

之前一直以传统后端的思维来写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对象也被修改了


file

特定地,如果希望被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'
};

最终打印的结果为


file

可以看到结果中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);

运行结果为:


file

可以看到,在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);
});
file

炒鸡辣鸡原创文章,转载请注明来源

相关文章

  • 传统后端开发者视角学习异步Nodejs的血泪笔记

    之前一直以传统后端的思维来写nodejs的代码,发现运行结果与我的同步思维方式不太一样,所以需要全面将nodejs...

  • 6. 异步编程

    NodeJS最大的卖点——事件机制和异步IO,对开发者并不是透明的。开发者需要按异步方式编写代码才用得上这个卖点,...

  • 回调,同步异步

    nodejs学习笔记 标签:node 异步 回调 单线程 1. callback 最简单的回调 注意回调的理解:...

  • 真正认识nodejs,这是一篇关于nodejs学习的文章

    nodejs学习笔记 原生模块 http:开启一个后端服务 src :获取客户端请求地址相关的信息 _ _dirn...

  • 2019 最新前后端编程学习视频

    2019 最新前后端编程学习视频 TypesScript + Nodejs + Express + Mongoos...

  • XDH_LESSON5

    nodejs io交互nodejs最大特性是采用异步IO与文件驱动的架构设计,对于高并发的解决方案,传统的架构是多...

  • Nodejs入门文章推荐

    对于前端开发者来说,Nodejs也许是从前端踏入后端的一个很好的平台,因为不需要重新学习新的语言了,但是Nodej...

  • 微信小程序开发——学习笔记(一)

    微信小程序开发——学习笔记(一) 前期准备 软件下载:Nodejs(8.0以上)微信开发者工具(使用最新版) 微信...

  • 深入浅出nodejs笔记

    Node.js是一个后端的Javascript运行环境。特点:事件驱动、异步编程nodejs的包结构如下: 一个p...

  • nodejs笔记-异步编程

    1.函数式编程 1.1高阶函数 函数参数只接受基本数据类型或者对象引用,返回值也是基本数据类型和对象引用。 高阶函...

网友评论

      本文标题:传统后端开发者视角学习异步Nodejs的血泪笔记

      本文链接:https://www.haomeiwen.com/subject/asbsmktx.html