那些年,在nodejs上踩过的坑
原文:http://cnodejs.org/topic/4fc7789a8be5d070121141cd
-----------------------------------------------------------
自己寫nodejs也有一段時(shí)間,踩過(guò)很多坑(而且大部分是自己給自己埋),也見過(guò)很多別人踩過(guò)的坑,原因其實(shí)也很簡(jiǎn)單,要么是對(duì)這個(gè)知識(shí)點(diǎn)理解不夠深入,要么就是編碼的習(xí)慣不好。這段響應(yīng)朋春大牛的號(hào)召,打算陸陸續(xù)續(xù)整理下這些坑,算是給自己一個(gè)備忘,同時(shí)也希望能對(duì)大家有所幫助。
1. callback
事件回調(diào)是nodejs非常常見的一個(gè)應(yīng)用場(chǎng)景,那大家先來(lái)看看以下這段代碼是否存在什么問(wèn)題?
get(params, function(err, data) {if (err) {callback(err);}//對(duì)data進(jìn)行操作var row = data[0]; });看出來(lái)了吧。對(duì),就是err存在時(shí),callback之后,接下來(lái)的代碼還是要執(zhí)行的。而這時(shí),data值是什么,我們往往是沒(méi)辦法控制的。如果data這時(shí)返回的是undefined,那么就悲劇了,程序肯定報(bào)錯(cuò)。當(dāng)然解決方法很簡(jiǎn)單,就是在callback之前加個(gè)return即可:
get(params, function(err, data) {if (err) {return callback(err);}//對(duì)data進(jìn)行操作var row = data[0]; });這個(gè)知識(shí)點(diǎn)并不是很難,但往往是初學(xué)者特別容易犯的錯(cuò),甚至已經(jīng)寫了很久代碼的同學(xué)也會(huì)偶爾犯這種低級(jí)錯(cuò)誤。
再來(lái)一個(gè)更隱蔽的:
db.get(key, function(err, data) {if (err) {return callback(err);}try {callback(null, JSON.parse(data.toString()))} catch(e) {callback(e);} });看似沒(méi)有任何問(wèn)題吧。嘿嘿,揭曉答案, 對(duì),被回調(diào)兩次。callback(null, Error)一次,callback(e),具體比如:
function asyncfun(data, callback) {try {callback(null, JSON.parse(data.toString()));} catch (e) {callback(e);} } var json = {'a': 'b'}; var jsonstr = JSON.stringify(json); var d = new Buffer(jsonstr);asyncfun(d, function(err, data) {console.log(err);throw new Error('new Error'); });運(yùn)行結(jié)果:
null [Error: new Error]這在一個(gè)大項(xiàng)目絕對(duì)是坑爹了,排錯(cuò)都需要很久。
ps:之前的描述存在問(wèn)題,謝謝蘇千的指正。
2. buffer
還是老規(guī)矩,先看代碼:
var data = ""; res.on('data', function (chunk) { data += chunk; }) .on("end", function () { });這段代碼在chunk都是ascii碼數(shù)據(jù)或者數(shù)據(jù)量比較少時(shí)是沒(méi)有問(wèn)題,但如果你的數(shù)據(jù)是大量中文的話,恭喜你,中槍了,會(huì)出現(xiàn)亂碼。其原因是兩個(gè)chunk(Buffer對(duì)象)的拼接并不正常,相當(dāng)于進(jìn)行了buffer.toString() + buffer.toString()。如果buffer不是完整的,則toString出來(lái)后的string是存在問(wèn)題的(比如一個(gè)中文字被截?cái)?#xff09;。具體可以參見樸靈寫得這篇文章:http://cnodejs.org/topic/4faf65852e8fb5bc65113403
3. 深度嵌套
很多剛開始寫nodejs代碼的人,由于思路還停留在同步的思維,所以或多或少寫過(guò)這樣的代碼:
func1(err, function(err1, data1) {func2(err1, function(err2, data2) {func3(err3, function(err3, data3) {func4(err4, function(err4, data4) {.......})})}) })先別說(shuō)這樣的代碼是否易于維護(hù),光樣子就夠難看,代碼都“斜”了。不怕大家恥笑,我自己剛開始就寫時(shí)也寫過(guò)這樣“坑爹”的代碼,為此自己當(dāng)時(shí)還寫了篇《如何讓nodejs同步操作》講如何解決這個(gè)問(wèn)題。不過(guò)從源頭上,大家還是要盡量避免采用這種同步的方法,因?yàn)閚odejs得優(yōu)勢(shì)就在于異步,硬生生要做成同步絕對(duì)吃力不討好
總結(jié)
以上是生活随笔為你收集整理的那些年,在nodejs上踩过的坑的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android之NetworkOnMai
- 下一篇: MR程序的几种提交运行模式