摘要

作为一个一直用java来写后端的程序员用NodeJS来写后台,实在不是很爽。这里记下这两个月的NodeJS学习所遇之坑,与java转NodeJS的同仁共勉。学习时间不长,若有理解错误,望指正。

一.JS基本

exports,module.exports

  • exports 就是module.exports的引用
  • 在module 被计算之前,会将module.exports的值赋给exports
  • 当module.exports赋值之后,再对exports改值,不会影响module.exports的值,而外部

    require module的时候,如果module.exports有定义,调用的是module.exports的值。

    eg1.
module.exports.hello = true; // Exported from require of module
exports = { hello: false }; // Not exported, only available in the module

eg2.

module.js

module.exports = 'a';
exports.B = 'b';

call.js

var module = require('module');
console.log(module.B);
//undefined
  • exports 就是传统的module实例,可以exports 变量,也可以exports 方法,调用的时候都一样,通过

    instance.xxx来调用

eg. module.js

exports.A = 'a'
exports.add = function add(a, b){
return a+b;
}

call.js

var module = require('module');
module.A;
module.add(xx,xx);
  • module.exports可以将module,exports成任何合法的js 类型,boolean,JSON,function都可以。

    从这点上说,就不能将javascript中的module类比成java中的类/实例。
module.exports = function (a, b) {
return a + b;
}

import 某个module的属性

与直接import不同

import { test } from ‘xxx’

issue

class 与instance

js中并没有class,一切皆为对象。面向对象的实现是通过prototype来实现的。

例如一般在某个文件中调用某个js文件,就是在文件开始部分require,然后在文件中

各处引用。而这点与java不同,java是首先import,然后具体用的时候需要new 一个instance再使用

js中require 以后直接使用。不需要new instance。所以各处用的都是同一个instance。

如果想new一个object,创建新的instance,则需要使用原型。这样每个new出来的对象就有对应的

原型方法了。

eg.

test.js

// 类似于构造函数
function Test() { } Test.prototype.add = function (a,b) {
return a+b;
};
module.exports = Test;

call.js

require Test from 'test';
function sub(){
var test1 = new Test();
test1.add();
}

作用域

对于方法而言,js没有类似于java的那么强的域控制public,protected,private

就分内部与外部,只在函数内部使用的就不要export出去。

二.异步回调

js 代码写起来和java代码最大的不同就是回调了。

java代码基本消灭了随意跳转的goto。阅读代码块或者写代码块时基本就是按照从上

到下的顺序即可。因为java代码都是同步执行的。而JS很多都是异步执行,所以如果你想

你的逻辑是顺序执行的话,必须等待异步执行返回结果后,再去执行下面的代码。因为js

方法大多是非阻塞。

—-2017.3.14更新———-

其实这代表了两种不同的并发处理方式,一种是java的,基于线程的并发,一个task一个线程。

写起来也是顺序执行的。但是task增多,多个线程之间切换代价昂贵,可能会导致吞吐量下降。

而nodejs,则是基于事件的并发,单线程处理事件,每个并发流实现为一个有限状态机。所以需要回调。应用直接控制。但是当并发负载增加的时候,吞吐量饱和响应时间线性增长

还有一种的话就是之前介绍的cassandra实现的SEDA模型

eg.实现查mongo数据库

java code

MongoClient  client = new MongoClient(url);
Collection coll = client.getCollection('test');
ResultSet<String> rs = coll.find({});

而js则是

MongoClient.connect(url, function(err, db) {
//回调,等待连接成功,才能执行下一步。
if (err) {
callback(err);
}
var coll = db.collection('test');
coll.find({name:"mike"}).toArray(function(err, results) {
console.log(results);
db.close();
});
});

三.内存溢出

NodeJs使用google V8来管理内存,V8会将js代码编译为本地代码,然后执行它。

V8会按需进行内存的分配和释放。和JVM差不多了。将内存区域分区,

  • 代码区域


  • 值类型的数据,内部变量,控制程序的指针。


  • 保存引用类型(对象,字符串,闭包)

在做mongodb数据大量插入的时候遇到过一次内存溢出的问题,所以需要分析溢出原因,

java中一般是dump处文件,然后用其他工具分析对象。NodeJs也类似。

var heapdump = require('heapdump');
heapdump.writeSnapshot();

然后在chrome中的Profile工具来分析溢出对象。但是实际中此效果不好,原因是chrome的内存不够大(可能需要调整浏览器内存大小),另外结果不是很直观。还可以使用util包中输出内存占用

var util = require('util');
console.log(util.inspect(process.memoryUsage()));

内存溢出原因:

在上面提到过在js中基本都是回调函数,mongo插入同样也是。使用mongo.insertMany(array)来批量插入提高性能。同时充分利用异步特点,使用async.each来控制,模拟多线程并发。但是这边就存在一个问题,有经验的老手就能看出来了,插入的数据array占用的内存什么时候释放。mongo.insertMany调用开始,到真正插入到db中需要一定时间。插入上千万条数据的,内存回收不及时的话肯定是要溢出的。所以要加一层并发控制,比如说以10万条数据为内层并发,这些数据的插入是并发操作的,无序的,等这一批数据插入成功后,再进行下一批数据插入,释放内存。

四.打包

java中依赖其他包,使用jar包。build工具可以用maven,gradle。

nodejs中依赖其他包,使用module.使用npm来构建

在package.json中的 files属性中定义要打包的文件

“files”: [

“src/publish”,

],

在main属性中定义main文件

“main”: “src/index.js”,

使用npm publish命令到repository。如果是本地的调用,使用npm pack 打包

在其他project中使用 npm install -s $PATH/publish-service-0.0.1.tgz添加引用

五.参考

http://www.hacksparrow.com/node-js-exports-vs-module-exports.html

https://cnodejs.org/topic/55accdeab4ab1d7d02bf0d8c

http://wwsun.github.io/posts/understanding-nodejs-gc.html

java程序员的NodeJS初识篇的更多相关文章

  1. 为何我建议1-3年的Java程序员仔细看看这篇文章

    此文的目的是为了督促自己去不断学习,让自己有更明确的方向去提升自己.以技能树为基础,以面试要点为大纲,我觉得比抓住什么看什么要更有目的,更能坚持下去.世界瞬息万变,我们要时刻准备着.时刻提高着自己,才 ...

  2. Java程序员金三银四精心准备的面试题及答案(基础篇)

    1.面向对象的特征有哪些方面? [基础] 答:面向对象的特征主要有以下几个方面: 1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问 ...

  3. Java 程序员们值得一看的好书推荐

    "学习的最好途径就是看书",这是我自己学习并且小有了一定的积累之后的第一体会.个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一 ...

  4. 分享下对JAVA程序员成长之路的总结<转>

    我也搞了几年JAVA了,由于一向懒惰,没有成为大牛,只是一普通程序猿,手痒来给新人分享下从新手成长为老鸟的已见.   首先初识语法的阶段,必须要学会怎么操作对象,操作if和for,操作list set ...

  5. Java 程序员们值得一看的好书推荐[转载]

    “学习的最好途径就是看书“,这是我自己学习并且小有了一定的积累之后的第一体会.个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他 ...

  6. Java教程-Java 程序员们值得一看的好书推荐

    学习的最好途径就是看书“,这是我自己学习并且小有了一定的积累之后的第一体会.个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他资 ...

  7. 【转载】分享下多年积累的对JAVA程序员成长之路的总结

    注:该文是从百度贴吧转载过来,之前看到觉得写得还不错,对Java开发学习者来说很有意义的,可以看看. 我也搞了几年JAVA了,由于一向懒惰,没有成为大牛,只是一普通程序猿,不爱玩社交网站,不爱玩微博, ...

  8. 分享下多年积累的对JAVA程序员成长之路的总结

    http://blog.csdn.net/zhongzelin/article/details/8643269我也搞了几年JAVA了,由于一向懒惰,没有成为大牛,只是一普通程序猿,不爱玩社交网站,不爱 ...

  9. 前后端分离时代,Java 程序员的变与不变!

    事情的起因是这样的,有个星球的小伙伴向邀请松哥在知乎上回答一个问题,原题是: 前后端分离的时代,Java后台程序员的技术建议? 松哥认真看了下这个问题,感觉对于初次接触前后端分离的小伙伴来说,可能都会 ...

随机推荐

  1. Python Trick —— 命令行显示

    1 应用场景 在命令行展示下,有以下两种场景. 进度条显示.在同一行展示不断的更新的进度条. 信息显示/隐藏控制.比如希望向多个用户展示不同信息,各个用户彼此保密. 2 进度条展示 跟c语言类似,打印 ...

  2. Codeforces 1015F Bracket Substring AC自动机 + dp

    Bracket Substring 这么垃圾的题怎么以前都不会写啊, 现在一眼怎么就会啊.... 考虑dp[ i ][ j ][ k ][ op ] 表示 已经填了 i 个空格, 末尾串匹配到 所给串 ...

  3. mongDB数据库 小白学习

    一  安装配置 1.配置文件mongod.cfg (路径:D:\data\config\mongod.cfg) 如下: systemLog: destination: file path: D:\da ...

  4. java类路径classpath

    java编译器编译.java文件和java虚拟机执行.class文件时的路径和写法不一样. 在没有设置任何classpath环境变量的情况下,javac可以编译全路径的.java文件.例如: java ...

  5. PDF文件优缺点

    PDF的优点: 一般公司的公文档都是用PDF格式传递给员工,因为PDF可防止他人无意中触到键盘修改文件内容. 再有就是,当我们将毕业设计报告用word编辑后,发送给导师查看时,也建议采用PDF格式.因 ...

  6. Codeforces 446A. DZY Loves Sequences (线性DP)

    <题目链接> 题目大意: 给定一个长度为$n$的序列,现在最多能够改变其中的一个数字,使其变成任意值.问你这个序列的最长严格上升子段的长度是多少. #include <bits/st ...

  7. java -ui自动化初体验

    本文来讲一下ui自动化的环境搭建,以及最初级的打开网页操作 说起ui自动化,想想大概是前年的时候我开始接触和学习的吧,怎么说呢无论是pc还是app,ios还是android,确实很神奇而且很华丽,但是 ...

  8. Ubuntu全盘备份与恢复,亲自总结,实测可靠

    https://blog.csdn.net/sinat_27554409/article/details/78227496 Ubuntu全盘备份与恢复,亲自总结,实测可靠 初学者在使用Ubuntu这类 ...

  9. 百度TTS的来由

    #### https://home-assistant.io/components/tts.baidu/#### https://github.com/charleyzhu/HomeAssistant ...

  10. 201771010126 王燕《面向对象程序设计(Java)》第十四周学习总结(测试程序11)

    实验十四  Swing图形界面组件 理论部分: 不使用布局管理器 有时候可能不想使用任何布局管理器,而只 是想把组件放在一个固定的位置上.下面是将一 个组件定位到某个绝对定位的步骤: 1)将布局管理器 ...