成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

給Node.js新手的7條小建議

Atom / 1167人閱讀

摘要:不知不覺(jué)的已經(jīng)用有將近一年了,這里我有幾條出自實(shí)踐的建議送給剛剛?cè)腴T的的朋友。命名而不是匿名在中,我們可以創(chuàng)建匿名對(duì)象和匿名函數(shù)。一般來(lái)說(shuō),匿名函數(shù)可以讓代碼更加簡(jiǎn)短精悍。然而,對(duì)這些對(duì)象或函數(shù)進(jìn)行命名,則有利于調(diào)試和優(yōu)化。

不知不覺(jué)的已經(jīng)用Node.js有將近一年了,這里我有幾條出自實(shí)踐的node.js建議送給剛剛?cè)腴T的node.js的朋友。

命名而不是匿名

在JavaScript中,我們可以創(chuàng)建匿名對(duì)象和匿名函數(shù)。一般來(lái)說(shuō),匿名函數(shù)可以讓代碼更加簡(jiǎn)短精悍。

然而,對(duì)這些對(duì)象或函數(shù)進(jìn)行命名,則有利于調(diào)試和優(yōu)化。以下是我從Chrome DevTool的文章中借用的圖片:

很明顯,命名的實(shí)體更利于調(diào)試和優(yōu)化。

盡早解引用

JavaScript的GC以一種類似引用計(jì)數(shù)的算法工作,一個(gè)對(duì)象當(dāng)且僅當(dāng)所有指向它的引用全部釋放之后,它本身才會(huì)被釋放掉。

然而可能你有其他的閉包或者全局對(duì)象持有它的引用,從而阻止了垃圾回收。為避免這一現(xiàn)象,應(yīng)當(dāng)盡早地解除不必要的引用:

var some_var = new net.Server();
// other code...
var i_want_it_temperoray = some_var;
some_operation(i_want_it_temperoray);
i_want_it_temperoray = null; // derefernce
// other code...

如果閉包中尚有一個(gè)變量未能被釋放,那么整個(gè)閉包都有可能無(wú)法被回收,從而造成其它對(duì)象也無(wú)法釋放。

現(xiàn)在有很多工具可以輔助我們監(jiān)視內(nèi)存的變化情況,比如heapdump、webkit-devtools-agent等等。同時(shí),這也更加說(shuō)明了為什么要盡可能使用命名而不是匿名的對(duì)象。

別復(fù)制代碼

我用Node.js開(kāi)發(fā)的項(xiàng)目代碼變化非??欤貥?gòu)也很頻繁,常常會(huì)到處復(fù)制代碼。然而每當(dāng)我這樣做的時(shí)候,后來(lái)都會(huì)發(fā)現(xiàn)某些變量要么就是忘了改名,要么就是有些變量壓根就不存在了,導(dǎo)致代碼變得極為不穩(wěn)定。

JS是一門高度動(dòng)態(tài)的語(yǔ)言,它不像C++這樣可以利用編譯器做靜態(tài)檢查,因此你幾乎沒(méi)有機(jī)會(huì)依靠工具檢查出這些問(wèn)題。所以我的建議是,盡可能地自己再輸入一遍代碼,這樣IDE或者編輯器有機(jī)會(huì)利用代碼自動(dòng)補(bǔ)全來(lái)為你檢查。如果你的IDE還沒(méi)這功能,那你真得考慮換掉它了。

慎重引入新模塊

Node.js社區(qū)非?;钴S,有成千上萬(wàn)的現(xiàn)成模塊可以取用,然而其中有些其實(shí)已經(jīng)沒(méi)人管了。Node.js的API也常常發(fā)生變化,適配node v0.8.x的模塊,有可能不支持v0.10.x。

因此當(dāng)你考慮引入新的模塊的時(shí)候,務(wù)必先去它的pull request列表或者issue列表看看,確認(rèn)一下這個(gè)模塊是不是已經(jīng)被拋棄,或者存在重大的隱患。

用async.js或者promise

Node.js基于回調(diào)。因?yàn)榛卣{(diào)的本質(zhì),我們很容易寫(xiě)出嵌套多層的回調(diào)函數(shù)?;卣{(diào)對(duì)于異步來(lái)說(shuō)是好事,但對(duì)于代碼維護(hù)來(lái)說(shuō)卻是壞事。

如果你發(fā)現(xiàn)代碼需要3層以上的回調(diào)函數(shù)嵌套,那你應(yīng)該考慮一下,要不要使用async.js或者基于promise概念的模塊。

以下是一個(gè)用async.js寫(xiě)出來(lái)的一系列異步操作:

async.auto([
  "init_logger": function(done){
    set_handlers_to_logger(done);
  },
  "load_config": ["init_logger", function(done){
    load_my_config(done);
  }],
  "init_database": ["load_config", function(done){
    connect_to_db_here(done);
  }],
  // 假定open_cache與數(shù)據(jù)庫(kù)無(wú)關(guān)
  "open_cache": ["load_config", function(done){
    open_cache_here(done);
  }],
  // warm_up通常用于從數(shù)據(jù)庫(kù)預(yù)先抓取一些數(shù)據(jù)
  // 注意,warm_up只會(huì)在"init_database"以及"open_cache"結(jié)束后執(zhí)行
  "warm_up": ["init_database", "open_cache", function(done){
    fetch_some_data(done);
  }],
  "init_routers": ["load_config", function(done){
    install_routers(done);
  }],
  "emit_out": ["warm_up", "init_routers", function(done){
    notify_others(done);
  }]
], function(err) {
  if(err){
    // 在這處理異常
  }
});

我對(duì)promise相關(guān)的模塊不是很熟,但使用Q,應(yīng)該可以寫(xiě)出這樣的代碼,,同樣易于閱讀:

Q.nfcall(function init_logger(){
  set_handlers_to_logger();
})
.then(function load_config(){
  load_my_config();
})
.then(function init_database(){
  connect_to_db_here();
})
.then(function open_cache(){
  open_cache_here();
})
.then(function warm_up(){
  fetch_some_data();
})
.then(function init_routers(){
  install_routers();
})
.then(function emit_out(){
  notify_others();
})
.catch(function (error) {
    // 在這處理異常
})
.done();

選取什么樣的庫(kù)來(lái)簡(jiǎn)化邏輯一般都是隨便你。通常來(lái)說(shuō),async.js非常簡(jiǎn)單,而Q則更加靈活強(qiáng)大。

  

比如說(shuō)async.js中各個(gè)函數(shù)獨(dú)立而不嵌套,因此如果你想通過(guò)捕獲某個(gè)函數(shù)中的變量就顯得有些困難,而在Q中就可以使用嵌套的then語(yǔ)句。

本來(lái)我還想寫(xiě)一寫(xiě)不使用任何輔助模塊的上述代碼,但其實(shí)我都很懷疑自己能不能寫(xiě)對(duì)。

另外,你是CoffeeScript的擁泵么?如果是,那你還可以嘗試一下IcedCoffeeScript。IcedCoffeeScript在語(yǔ)言層面上提供了兩個(gè)非常有用的關(guān)鍵字: awaitdefer?;旧纤械牧鞒炭刂贫伎梢酝ㄟ^(guò)這兩個(gè)關(guān)鍵字進(jìn)行改造。不過(guò)我本人對(duì)IcedCoffeeScript并不熟悉,所以就不在這獻(xiàn)丑了。這里感謝brettof86向我介紹了這一利器,不過(guò)我還需要花些時(shí)間來(lái)熟悉它。

客戶端也許特別慢

用Node.js的時(shí)候我們可能會(huì)變得有點(diǎn)過(guò)于理想化了,因此很容易寫(xiě)出下面這樣的聊天室代碼:

var net = require("net");
var clientList = [];
var server = net.createServer(function(c) { //"connection" listener
  console.log("server connected");
  clientList.push(c);
  c.on("end", function() {
    console.log("server disconnected");
    unpipe_all(c, clientList);
    remove_from(c, clientList);
  });
  clientList.forEach(function(item){
    item.pipe(c); // 注意這
    c.pipe(item); // 還有這
  });
});
server.listen(8124, function() { //"listening" listener
  console.log("server bound");
});

我覺(jué)得整個(gè)結(jié)構(gòu)沒(méi)什么大問(wèn)題,但當(dāng)我們遇上網(wǎng)絡(luò)狀況不好的客戶端時(shí),情況就不大好了。這里的兩個(gè)pipe會(huì)把數(shù)據(jù)緩存在內(nèi)存中,因此當(dāng)客戶端不能及時(shí)接收數(shù)據(jù)時(shí),這些數(shù)據(jù)就會(huì)大量滯留在內(nèi)存當(dāng)中。我們往往假設(shè)客戶端的速度還不錯(cuò),但其實(shí)那都只是假設(shè)!

我想到的一個(gè)方法是,用一個(gè)中間件來(lái)做緩存,當(dāng)數(shù)據(jù)太多時(shí)使用文件緩沖,而數(shù)據(jù)不多則用內(nèi)存,如下:

Delegate delegate; 
clientList.forEach(function(item){
  delegate.append(item);
  // delegate內(nèi)部會(huì)有一個(gè)與文件關(guān)聯(lián)的緩存
    // 如果數(shù)據(jù)太大則把數(shù)據(jù)存入文件
});

如果你有其它的方案來(lái)處理這種情況,不妨也分享一下:)

用事件通知完成,而且不要太早

大多數(shù)小對(duì)象都是同步構(gòu)造的,但對(duì)于某些封裝了復(fù)雜操作的對(duì)象來(lái)說(shuō),初始化都有可能是異步的。

如果一個(gè)對(duì)象需要異步構(gòu)造,那么最好使用事件通知完成。這時(shí)你要留意官方文檔 中的一小段話:

  

This is important in developing APIs where you want to give the user the chance to assign event handlers after an object has been constructed, but before any I/O has occurred.

  function MyThing(options) {
    this.setupOptions(options);
  
    process.nextTick(function() {
       this.startDoingStuff();
    }.bind(this));
  }
  
  var thing = new MyThing();
  thing.getReadyForStuff();
  
  // thing.startDoingStuff() gets called now, not before.

典型的解決方案是,在構(gòu)造結(jié)束時(shí)用process.nextTick來(lái)發(fā)消息:

function SomeTCPServer(options) {
  var self = this;
  // 其他可能異步的初始化工作
  process.nextTick(function(){
    self.emit("ready");
  });
}

// 其他代碼
var server = new SomeTCPServer(ops);
server.on("ready", function when_ready(){
  // 其它事情
});

因?yàn)橛玫氖?b>process.nextTick,when_ready不會(huì)錯(cuò)過(guò)ready事件。

其它建議?

我暫時(shí)就想起來(lái)這么多,因?yàn)槲易约阂膊皇荖ode.js的真正專家。不過(guò)我還是希望上面的幾條能對(duì)新手有所幫助,歡迎大家指出上面的任何錯(cuò)漏,謝啦。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/77942.html

相關(guān)文章

  • node.js中文資料導(dǎo)航

    摘要:中文資料導(dǎo)航官網(wǎng)七牛鏡像深入淺出系列進(jìn)階必讀中文文檔被誤解的編寫(xiě)實(shí)戰(zhàn)系列熱門模塊排行榜,方便找出你想要的模塊多線程,真正的非阻塞淺析的類利用編寫(xiě)異步多線程的實(shí)例中與的區(qū)別管道拒絕服務(wù)漏洞高級(jí)編程業(yè)界新聞看如何評(píng)價(jià)他們的首次嘗鮮程序員如何說(shuō)服 node.js中文資料導(dǎo)航 Node.js HomePage Node官網(wǎng)七牛鏡像 Infoq深入淺出Node.js系列(進(jìn)階必讀) Nod...

    geekidentity 評(píng)論0 收藏0
  • 貓頭鷹深夜翻譯:在JAVA中記錄日志十個(gè)小建

    摘要:是指可能導(dǎo)致程序終止的非常嚴(yán)重的時(shí)間。具有最高的級(jí)別,旨在關(guān)閉中的日志功能。因此為每一個(gè)消息選擇一個(gè)合適的日志級(jí)別是非常重要的。日志的個(gè)小建議將日志訪日代碼塊它能顯著的減少因?yàn)樽址唇佣鴰?lái)的性能的影響。 前言 首先,這篇文章沒(méi)有進(jìn)行任何的日志功能的詳細(xì)介紹,而是對(duì)日志提出了幾種最佳實(shí)踐。適合對(duì)日志記錄有所了解的同學(xué)閱讀。下面是正文: JAVA日志管理既是一門科學(xué),又是一門藝術(shù)。科學(xué)...

    venmos 評(píng)論0 收藏0
  • PHP開(kāi)發(fā)銀聯(lián)云閃付二維碼支付

    摘要:最近剛好有在研究銀聯(lián)云閃付的支付模塊,所以就寫(xiě)篇總結(jié)分享給大家。很方便的就是,銀聯(lián)云閃付的接入給我們準(zhǔn)備了測(cè)試模式,就是你并不需要真的有商戶號(hào)才能開(kāi)發(fā),不像微信支付那樣非要有商戶號(hào)才能測(cè)試開(kāi)發(fā)。 你好,是我琉憶。最近剛好有在研究銀聯(lián)云閃付的支付模塊,所以就寫(xiě)篇總結(jié)分享給大家。 這算是第二次接觸支付的東西了,接觸得最多的是接入微信支付,自己也有相關(guān)的總結(jié)文章,可以去segmentfaul...

    王笑朝 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<