javascript
java程序员的NodeJS初识篇
摘要
作為一個一直用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.
eg2.
module.js
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中的類/實例。
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
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
而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也類似。
然后在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
轉載于:https://www.cnblogs.com/stoneFang/p/6715270.html
總結
以上是生活随笔為你收集整理的java程序员的NodeJS初识篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转载】C/C++中long long与
- 下一篇: ASP.NET Core MVC上传、导