
èè
ããã®ã³ã¡ã³ã
ãã®èšäºã¯æ°ãããã®ã§ãããæ°æ©èœã«é¢ãããã®ã§ã¯ãããŸããã ããã¯äžæ žãã€ãŸããã©ãããã©ãŒã ã«é¢ãããã®ã§ãããåã«ããªã声ãwebpackãåã«äœ¿çšããå€ãã®äººãçããªããããããªããšããäºå®ã«ã€ããŠã§ãã
詳现ãèªãïŒ
ã©ã ãã³ã®ã³ã¡ã³ãïŒ
habrahabr.ru/company/mailru/blog/283228/#comment_8890604
ã¢ã€ãã£ããã®ã³ã¡ã³ãïŒ
habrahabr.ru/company/mailru/blog/283228/#comment_8890476
Suvitrufã³ã¡ã³ãïŒ
habrahabr.ru/company/mailru/blog/283228/#comment_8890430
ãã®æçš¿ã®ã¢ã€ãã¢ã¯ãKyle Simpsonã®äžé£ã®æžç±ã
You Do n't Know JavaScript ãã«è§ŠçºãããŸããã 圌ãã¯ãã®èšèªã®åºç€ãåŠã¶è¯ãã¹ã¿ãŒãã§ãã Nodeã¯ããã®èšäºã§èª¬æããå°ããªéããé€ããŠãã»ãŒåãJavaScriptã§ãã 以äžã®ãã¹ãŠã®ã³ãŒãã¯ã
ãªããžããªãã
code
ãã©ã«ããŒããããŠã³ããŒãã§ããŸãã
Nodeã«ç
©ããããã®ã¯ãªãã§ããïŒ Nodeã¯JavaScriptã§ãããJavaScriptã¯ã»ãŒãã¹ãŠã®å Žæã§äœ¿çšãããŠããŸãïŒ éçºè
ã®å€§å€æ°ãNodeãå®å
šã«ãã¹ã¿ãŒããã°ãäžçã¯è¯ããªãã§ãããã ããè¯ãã¢ããªã±ãŒã·ã§ã³ãããè¯ãç掻ïŒ
ãã®èšäºã¯ãNodeã®æãèå³æ·±ãã³ã¢æ©èœã®çŸå®çãªå€èŠ³ã§ãã èšäºã®ããŒãã€ã³ãïŒ
- ã€ãã³ãã«ãŒãïŒãã³ããããã³ã°I / Oãå®è£
ããããã®éèŠãªæŠå¿µã®æŽæ°
- ã°ããŒãã«ãªããžã§ã¯ããšããã»ã¹ïŒè©³çŽ°æ
å ±ã®ååŸæ¹æ³ã
- ã€ãã³ããšããã¿ãŒïŒã€ãã³ãããŒã¹ã®ãã¿ãŒã³ã®éäžçãªçŽ¹ä»
- ã¹ããªãŒã ãšãããã¡ïŒããŒã¿ãæäœããå¹ççãªæ¹æ³
- ã¯ã©ã¹ã¿ãŒïŒããã®ãããªãã©ãŒã¯ããã»ã¹
- éåæãšã©ãŒåŠçïŒ AsyncWrapãDomainãããã³uncaughtException
- C ++ã®ã¢ããªã³ïŒã«ãŒãã«ã§ç¬èªã®éçºãè¡ããC ++ã§ç¬èªã®ã¢ããªã³ãäœæãã
ã€ãã³ãã«ãŒã
Nodeã®åºç€ãšãªãã€ãã³ãã«ãŒãããå§ããŸãããã
Node.jsã®éããããã³ã°I / Oãã®ãµã€ã¯ã«ã«ãããI / Oæäœã®å®è¡ãšäžŠè¡ããŠä»ã®ã¿ã¹ã¯ãæäœã§ããŸãã NginxãšApacheãæ¯èŒããŠãã ããã I / Oã®ãããã¯ã¯å®ããªããããNodeã¯éåžžã«é«éã§å¹ççã§ããã€ãã³ãã«ãŒãã®ãããã§ãã
Javaã§ä¿çäžã®
println
é¢æ°ã®ãã®åçŽãªäŸãèŠãŠãã ããã
System.out.println("Step: 1"); System.out.println("Step: 2"); Thread.sleep(1000); System.out.println("Step: 3");
ããã¯Nodeã³ãŒãã«å¹æµããŸãïŒå®å
šã§ã¯ãããŸãããïŒïŒ
console.log('Step: 1') setTimeout(function () { console.log('Step: 3') }, 1000) console.log('Step: 2')
ããã¯åãã§ã¯ãããŸããã éåææäœã®èŠ³ç¹ããèãå§ããŸãã Nodeã¹ã¯ãªããã®åºåã¯1ã2ã3ã§ãã ãããããã¹ããã2ãã®åŸã«ããã«åŒãããã°ãæåã«ããããå®è¡ããããããã
setTimeout
é¢æ°ã®ã³ãŒã«ããã¯ãå®è¡ãããŸãã ãã®ã¹ãããããèŠãŠãã ããïŒ
console.log('Step: 1') setTimeout(function () { console.log('Step: 3') console.log('Step 5') }, 1000); console.log('Step: 2') console.log('Step 4')
圌ã®äœæ¥ã®çµæã¯ã·ãŒã±ã³ã¹
setTimeout
ãŸããçç±ã¯ã
setTimeout
ãã€ãã³ãã«ãŒãã®å°æ¥ã®æéã«ã³ãŒã«ããã¯ãé
眮ããããã§ãã
ã€ãã³ãã«ãŒãã¯ã
for ⊠while
ãããªç¡éã«ãŒããšèããããšãã§ããŸãã 圌ã¯ãçŸåšãå°æ¥ããäœãããããšããªããšãã«ã ãç«ã¡æ¢ãŸããŸãã
ããããã³ã°I / OïŒãã«ãã¹ã¬ããJavaã€ãã³ãã«ãŒãã«ãããã·ã¹ãã ã¯ããå¹ççã«åäœããã¢ããªã±ãŒã·ã§ã³ã¯é«äŸ¡ãªI / Oæäœã®å®äºãåŸ
ã£ãŠããéã«ä»ã®ããšãè¡ãããšãã§ããŸãã
Node.jsã®éããããã³ã°I / Oããã¯ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ã¹ã¬ããã䜿çšããããäžè¬çãªåæå®è¡ã¢ãã«ãšã¯å¯Ÿç
§çã§ãã ãããã¯ãŒã¯ãããŒã¢ãã«ïŒã¹ã¬ããããŒã¹ã®ãããã¯ãŒã¯ïŒã¯éåžžã«éå¹ççã§ã䜿çšãéåžžã«å°é£ã§ãã ããã«ãNodeãŠãŒã¶ãŒã¯ããã»ã¹ãå®å
šã«ãããã¯ããããšãæããªããããããŸãã-ããã«ã¯ããã¯ããããŸããã
ãšããã§ãNode.jsã§ã¯ãããããã³ã°ã³ãŒããäœæã§ããŸãã ãã®ç°¡åãªã¹ãããããèŠãŠãã ããã
console.log('Step: 1') var start = Date.now() for (var i = 1; i<1000000000; i++) {
ãã¡ãããéåžžãã³ãŒãã«ã¯ç©ºã®ã«ãŒãã¯ãããŸããã ä»ã®äººã®ã¢ãžã¥ãŒã«ã䜿çšããå Žåãåæãæ€åºããããšãããå°é£ã«ãªãå¯èœæ§ããããŸããã€ãŸããã³ãŒãããããã¯ããŸãã ããšãã°ãã¡ã€ã³ã¢ãžã¥ãŒã«
fs
ïŒãã¡ã€ã«ã·ã¹ãã ïŒã«ã¯2ã€ã®ã¡ãœããã»ãããä»å±ããŠããŸãã åãã¢ã¯åãããšãè¡ããŸãããæ¹æ³ã¯ç°ãªããŸãã
fs
ã¢ãžã¥ãŒã«ã®ãããã¯ã¡ãœããã«ã¯ãååã«
Sync
ãšããåèªãå«ãŸããŠããŸãã
var fs = require('fs') var contents = fs.readFileSync('accounts.txt','utf8') console.log(contents) console.log('Hello Ruby\n') var contents = fs.readFileSync('ips.txt','utf8') console.log(contents) console.log('Hello Node!')
ãã®ã³ãŒãã®å®è¡çµæã¯ãNode / JavaScriptã®åå¿è
ã§ãå®å
šã«äºæž¬å¯èœã§ãã
data1->Hello Ruby->data2->Hello NODE!
ããããéåæã¡ãœããã«åãæ¿ãããšããã¹ãŠãå€ãããŸãã ãã³ããããã³ã°ã³ãŒãã®äŸã次ã«ç€ºããŸãã
var fs = require('fs'); var contents = fs.readFile('accounts.txt','utf8', function(err,contents){ console.log(contents); }); console.log('Hello Python\n'); var contents = fs.readFile('ips.txt','utf8', function(err,contents){ console.log(contents); }); console.log("Hello Node!");
å®è¡ã«ã¯æéããããããã
contents
ã¯æåŸã«è¡šç€ºãããã³ãŒã«ããã¯ã«ãå«ãŸããŸãã ãã¡ã€ã«ãèªã¿åã£ãåŸãã€ãã³ãã«ãŒãããããã«ç§»åããŸãã
Hello Python->Hello Node->data1->data2
äžè¬ã«ãã€ãã³ãã«ãŒããšãã³ããããã³ã°I / Oæäœã¯éåžžã«åŒ·åã§ãããå€ãã¯æ
£ããŠããªãéåæã³ãŒããèšè¿°ããå¿
èŠããããŸãã
ã°ããŒãã«ãªããžã§ã¯ã
éçºè
ããã©ãŠã¶ããŒã¹ã®JavaScriptãŸãã¯å¥ã®èšèªããNode.jsã«åãæ¿ããå Žåã次ã®è³ªåããããŸãã
- ãã¹ã¯ãŒããä¿åããå Žæã¯ïŒ
- ã°ããŒãã«å€æ°ãäœæããæ¹æ³ïŒããŒãã«ã¯
window
ããããŸããïŒïŒ - CLIå
¥åãOSããã©ãããã©ãŒã ãã¡ã¢ãªãããŒãžã§ã³ãªã©ã«ã¢ã¯ã»ã¹ããæ¹æ³ã¯ïŒ
ãããè¡ãã«ã¯ãç¹å®ã®ããããã£ãæã€ã°ããŒãã«ãªããžã§ã¯ãããããŸãã ãããã®ããã€ãã次ã«ç€ºããŸãã
global.process
ïŒããã»ã¹ãã·ã¹ãã ãç°å¢æ
å ±ïŒCLIå
¥åããŒã¿ããã¹ã¯ãŒãä»ãã®ç°å¢å€æ°ãã¡ã¢ãªãªã©ãåç
§ã§ããŸãïŒglobal.__filename
ïŒãã¡ã€ã«åãšããã®åŒã眮ãããŠããçŸåšå®è¡äžã®ã¹ã¯ãªãããžã®ãã¹ãglobal.__dirname
ïŒçŸåšå®è¡äžã®ã¹ã¯ãªãããžã®ãã«ãã¹ãglobal.module
ïŒãã®ãã¡ã€ã«ããã¢ãžã¥ãŒã«ãäœæããã³ãŒãããšã¯ã¹ããŒããããªããžã§ã¯ããglobal.require()
ïŒã¢ãžã¥ãŒã«ãJSONãã¡ã€ã«ããã³ãã©ã«ããŒãã€ã³ããŒãããããã®ã¡ãœããã
ããããçãããããŸã-ãã©ãŠã¶JavaScriptã®ã¡ãœããïŒ
global.console()
global.setInterval()
global.setTimeout()
åã°ããŒãã«ããããã£ã«ã¯ã
global.process
代ããã«
global.process
èšè¿°
process
ã ãã§ã倧æåã§å
¥åãããåå
GLOBAL
ããŸãã¯ååããŸã£ããä»ããã«ã¢ã¯ã»ã¹ã§ããŸãã
ããã»ã¹
ããã»ã¹ãªããžã§ã¯ãã«ã¯å€ãã®æ
å ±ãå«ãŸããŠãããããå¥ã®ç« ã«å€ããŸãã 以äžã«ãã®ããããã£ã®äžéšã瀺ããŸãã
process.pid
ïŒãã®Nodeã€ã³ã¹ã¿ã³ã¹ã®ããã»ã¹IDãprocess.versions
ïŒNodeãV8ãããã³ãã®ä»ã®ã³ã³ããŒãã³ãã®ç°ãªãããŒãžã§ã³process.arch
ïŒã·ã¹ãã ã¢ãŒããã¯ãã£process.argv
ïŒCLIåŒæ°process.env
ïŒç°å¢å€æ°
ããã€ãã®æ¹æ³ïŒ
process.uptime()
ïŒäœæ¥æéãååŸããŸãprocess.memoryUsage()
ïŒæ¶è²»ãããã¡ã¢ãªéãååŸããŸãprocess.cwd()
ïŒçŸåšã®äœæ¥ãã©ã«ããŒãååŸããŸãã ããã»ã¹ãèµ·åãããå Žæã«äŸåããªã __dirname
ãšæ··å __dirname
ãªãã§ãã ãããprocess.exit()
ïŒçŸåšã®ããã»ã¹ãçµäºããŸãã ããšãã°ãã³ãŒã0ãŸãã¯1ãæž¡ãããšãã§ããŸããprocess.on()
ïŒã€ãã³ãã«ã¢ã¿ããããŸããããšãã°ã `onïŒ 'uncaughtException'ïŒ
é£ãã質åïŒèª°ã奜ãã§ã誰ãã³ãŒã«ããã¯ã®æ¬è³ªãç解ããŠããŸããïŒ
誰ãã圌ããšãæãããŠãããããã圌ã¯
http://callbackhell.comãäœæããŸããã ãã®çšèªãããããããªãå Žåã¯ã次ã®å³ãã芧ãã ããã
fs.readdir(source, function (err, files) { if (err) { console.log('Error finding files: ' + err) } else { files.forEach(function (filename, fileIndex) { console.log(filename) gm(source + filename).size(function (err, values) { if (err) { console.log('Error identifying file size: ' + err) } else { console.log(filename + ' : ' + values) aspect = (values.width / values.height) widths.forEach(function (width, widthIndex) { height = Math.round(width / aspect) console.log('resizing ' + filename + 'to ' + height + 'x' + height) this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) { if (err) console.log('Error writing file: ' + err) }) }.bind(this)) } }) }) } })
ã³ãŒã«ããã¯å°çã¯èªã¿ã¥ãããããã§ééããç¯ãããšã¯ç°¡åã§ãã ããã§ã¯ãã³ãŒã«ããã¯ã䜿çšããªãå Žåãéçºã®èŠ³ç¹ããã®ã¹ã±ãŒãªã³ã°ã«ã¯ããŸã䟿å©ã§ã¯ãªãã®ã«ãã©ã®ããã«ã¢ãžã¥ãŒã«ã«åå²ããéåæã³ãŒããæŽçããŸããã
ã€ãã³ããšããã¿ãŒ
ã€ãã³ããšããã¿ãŒã¯ãã³ãŒã«ããã¯ã®å°çããŸãã¯éåœã®ãã©ãããã«å¯ŸåŠããããã«äœ¿çšãããŸãã 圌ãã®å©ããåããŠãã€ãã³ãã䜿çšããŠéåæã³ãŒããå®è£
ã§ããŸãã
èŠããã«ãã€ãã³ããšããã¿ã¯ã誰ã§ãèãããšãã§ããã€ãã³ãã®ããªã¬ãŒã§ãã Node.jsã§ã¯ãã€ãã³ãããšã«ããšããã¿ãŒãã³ãŒã«ããã¯ããã³ã°ã§ããæåååãå²ãåœãŠãããŸãã
ãšããã¿ãŒãšã¯ïŒ
- Nodeã§ã¯ãã€ãã³ãã¯ãªãã¶ãŒããŒãã¿ãŒã³ã䜿çšããŠåŠçãããŸãã
- ã€ãã³ãïŒãŸãã¯ãµããžã§ã¯ãïŒã¯ãããã«é¢é£ãããã¹ãŠã®æ©èœã远跡ããŸãã
- ãããã®é¢æ°âãªãã¶ãŒããŒâã¯ããã®ã€ãã³ããã¢ã¯ãã£ãã«ãªããšå®è¡ãããŸãã
ãšããã¿ã䜿çšããã«ã¯ãã¢ãžã¥ãŒã«ãã€ã³ããŒããããªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãäœæããå¿
èŠããããŸãã
var events = require('events') var emitter = new events.EventEmitter()
次ã«ãã€ãã³ãã¬ã·ãŒããŒãæ¥ç¶ããã€ãã³ããã¢ã¯ãã£ãå/éä¿¡ã§ããŸãã
emitter.on('knock', function() { console.log('Who\'s there?') }) emitter.on('knock', function() { console.log('Go away!') }) emitter.emit('knock')
EventEmitter
䜿çšããŠã圌ããç¶æ¿ããŠæçšãªããš
EventEmitter
ããŸãããã æããšãé±ããšããŸãã¯æ¯æ¥ãã¯ã©ã¹ãå®æçã«å®è£
ããå¿
èŠããããšããŸãã ãã®ã¯ã©ã¹ã¯ãä»ã®éçºè
ãæçµçµæãã«ã¹ã¿ãã€ãºã§ããããã«ååãªæè»æ§ãå¿
èŠã§ãã ã€ãŸããäœæ¥ã®æåŸã«ã誰ã§ãã¯ã©ã¹ã«äœããã®ããžãã¯ãé
眮ã§ããå¿
èŠããããŸãã
ãã®å³ã¯ãã€ãã³ãã¢ãžã¥ãŒã«ããã®ç¶æ¿ã䜿çšããŠ
Job
äœæãã
done
ã€ãã³ãã¬ã·ãŒããŒã䜿çšããŠ
Job
ã¯ã©ã¹ã®åäœãå€æŽããæ¹æ³ã瀺ããŠããŸãã
Node.jsã®ã€ãã³ããšããã¿ãŒïŒãªãã¶ãŒããŒãã¿ãŒã³Job
ã¯ã©ã¹ã¯ãã®ããããã£ãä¿æããŸãããåæã«ã€ãã³ããåãåããŸãã ããã»ã¹ã®æåŸã§ã
done
ã€ãã³ããèµ·åããã ãã§ãã
æåŸã«ã
Job
ã®åäœãå€æŽããŸãã
done
ãæž¡ããšãã€ãã³ãã¬ã·ãŒããŒãã¢ã¿ããã§ããŸãã
ãšããã¿ã«ã¯ä»ã®å¯èœæ§ããããŸãïŒ
emitter.listeners(eventName)
ïŒãã®ã€ãã³ãã®ãã¹ãŠã®åä¿¡è
ã®ãªã¹ãã圢æããŸããemitter.once(eventName, listener)
ã€ãã³ãåemitter.once(eventName, listener)
ïŒã¯ã³ã¿ã€ã ã€ãã³ãã¬ã·ãŒããŒãã¢ã¿ããããŸããemitter.removeListener(eventName, listener)
ïŒã€ãã³ãã¬ã·ãŒããŒãåé€ããŸãã
Nodeã¯ã©ãã§ããç¹ã«ã¡ã€ã³ã¢ãžã¥ãŒã«ã§ã€ãã³ããã¿ãŒã³ã䜿çšããŸãã ãããã£ãŠãã€ãã³ããæ£ãã䜿çšããã°ãæéã倧å¹
ã«ç¯çŽã§ããŸãã
ã¹ããªãŒã
Nodeã§å€§éã®ããŒã¿ãæ±ãå Žåãããã€ãã®åé¡ããããŸãã ããã©ãŒãã³ã¹ãäœäžããå Žåãããããããã¡ãµã€ãºã¯çŽ1 GBã«å¶éãããŸãã ããã«ã決ããŠçµãããªããšããæåŸ
ãæã£ãŠäœæãããç¡éã®ãªãœãŒã¹ã§äœæ¥ããæ¹æ³ã¯ïŒ ãã®ãããªç¶æ³ã§ã¯ãã¹ããªãŒã ã圹ç«ã¡ãŸãã
Nodeã®ã¹ããªãŒã ã¯æœè±¡åã§ãããããŒã¿ããã©ã°ã¡ã³ãã«é£ç¶çã«åå²ããããšã瀺ããŸãã ã€ãŸãããªãœãŒã¹ãå®å
šã«ããŒããããã®ãåŸ
ã€å¿
èŠã¯ãããŸããã ãã®å³ã¯ããããã¡ãªã³ã°ã®æšæºçãªã¢ãããŒãã瀺ããŠããŸãã
Node.jsã®ãããã¡ãªã³ã°ã¢ãããŒãããŒã¿ã®åŠçãåºåãéå§ããåã«ããããã¡ãå®å
šã«ããŒãããããŸã§åŸ
ã€å¿
èŠããããŸãã 次ã«ãããããããŒãã£ãŒããšæ¯èŒããŸãã ãã®å Žåãæåã®ãã£ã³ã¯ãååŸãããšããã«ãããŒã¿ã®åŠçããã³/ãŸãã¯åºåãããã«éå§ã§ããŸãã
Node.jsã§ã®ã¹ããªãŒã ã¢ãããŒãNodeã«ã¯4ã€ã®ã¿ã€ãã®ã¹ããªãŒã ããããŸãïŒ
- èªã¿åãå¯èœïŒãããããèªã¿åãããšãã§ããŸãã
- æžã蟌ã¿å¯èœïŒãããã«æžã蟌ãããšãã§ããŸãã
- äºéïŒæžã蟌ã¿ãšèªã¿åããã§ããŸãã
- å€æïŒããŒã¿ã®å€æã«äœ¿çšã§ããŸãã
äºå®äžãã¹ããªãŒã ã¯Nodeã®ããããå Žæã§äœ¿çšãããŸãã æã人æ°ã®ããã¹ããªãŒã ã®å®è£
ïŒ
- HTTPãªã¯ãšã¹ããšã¬ã¹ãã³ã¹ã
- æšæºå
¥åºåæäœã
- ãã¡ã€ã«ã®èªã¿åããšæžã蟌ã¿ã
ãªãã¶ãŒããŒãã¿ãŒã³ãæäŸããããã«ãã¹ããªãŒã âã€ãã³ãâã¯ãã€ãã³ããšããã¿ãªããžã§ã¯ãããç¶æ¿ããŸãã ããã䜿çšããŠãã¹ããªãŒã ãå®è£
ã§ããŸãã
èªã¿åãå¯èœãªã¹ããªãŒã ã®äŸ
äŸã¯ãæšæºå
¥åã¹ããªãŒã ã§ãã
process.stdin
ã§ãã ããã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã«å
¥ãããŒã¿ãå«ãŸããŠããŸãã ããã¯éåžžãããã»ã¹ãéå§ããããã«äœ¿çšãããããŒããŒãæ
å ±ã§ãã
data
ããã³
end
ã€ãã³ãã¯ã
stdin
ããããŒã¿ãèªã¿åãããã«äœ¿çšãããŸãã
data
ã€ãã³ãã®ã³ãŒã«ããã¯ã«ã¯ãåŒæ°ãšããŠ
chunk
ããããŸãã
process.stdin.resume() process.stdin.setEncoding('utf8') process.stdin.on('data', function (chunk) { console.log('chunk: ', chunk) }) process.stdin.on('end', function () { console.log('--- END ---') })
次ã«ã
chunk
å
¥åãšããŠããã°ã©ã ã«éãããŸãã ãã®ã€ãã³ãã¯ãçä¿¡æ
å ±ã®åèšéã«å¿ããŠãæ°åã¢ã¯ãã£ãåã§ããŸãã ã¹ããªãŒã ã®å®äºã¯ã
end
ã€ãã³ãã䜿çšããŠéç¥ããå¿
èŠããããŸãã
泚ïŒ
stdin
ã¯ããã©ã«ãã§äžæåæ¢ãããŠããŸã
stdin
ããããŒã¿ãèªã¿åãåã«
stdin
åºåããå¿
èŠããããŸãã
èªã¿åãå¯èœãªã¹ããªãŒã ã«ã¯ãåæçã«åäœãã
read()
ã€ã³ã¿ãŒãã§ã€ã¹ããããŸãã ã¹ããªãŒã ã®æåŸã§ã
chunk
ãŸãã¯
null
è¿ã
null
ã
while
æ¡ä»¶ã§
null !== (chunk = readable.read())
ã³ã³ã¹ãã©ã¯ããèšå®ããããšã«ããããã®åäœãå©çšã§ã
null !== (chunk = readable.read())
var readable = getReadableStreamSomehow() readable.on('readable', () => { var chunk while (null !== (chunk = readable.read())) { console.log('got %d bytes of data', chunk.length) } })
çæ³çã«ã¯ãã¹ã¬ããã®ãããã¯ãåé¿ããããã«ãã§ããã ãé »ç¹ã«Nodeã«éåæã³ãŒããèšè¿°ããããšèããŠããŸãã ãã ãããã£ã³ã¯ã®ãµã€ãºãå°ããã®ã§ãã¹ã¬ããããããã¯ããåæç
readable.read()
ãå¿é
ããå¿
èŠã¯ãããŸããã
èšé²ãããã¹ããªãŒã ã®äŸ
äŸã¯ãæšæºåºåã¹ããªãŒã ã§ãã
process.stdout
ã§ãã ã¢ããªã±ãŒã·ã§ã³ãé¢ããããŒã¿ãå«ãŸããŠããŸãã
write
æäœã䜿çšããŠã¹ããªãŒã ã«æžã蟌ãããšãã§ããŸãã
process.stdout.write('A simple message\n')
console.log()
ã䜿çšãããã®ããã«ãæšæºåºåã¹ããªãŒã ã«èšé²ãããããŒã¿ãã³ãã³ãã©ã€ã³ã«è¡šç€ºãããŸãã
ãã€ã
Nodeã«ã¯ãäžèšã®ã€ãã³ãã®ä»£ããã«
pipe()
ã¡ãœããããããŸãã 次ã®äŸã§ã¯ããã¡ã€ã«ããããŒã¿ãèªã¿åããGZipã䜿çšããŠå§çž®ããçµæããã¡ã€ã«ã«æžã蟌ã¿ãŸãã
var r = fs.createReadStream('file.txt') var z = zlib.createGzip() var w = fs.createWriteStream('file.txt.gz') r.pipe(z).pipe(w)
Readable.pipe()
ã¯ããŒã¿ã¹ããªãŒã ãåãåãããã¹ãŠã®ã¹ããªãŒã ãééããããã
pipe()
ã¡ãœãããããã§ãŒã³ãäœæã§ããŸãã
ãã®ãããã¹ããªãŒã ã䜿çšããå Žåãã€ãã³ããŸãã¯ãã€ãã䜿çšã§ããŸãã
HTTPã¹ããªãŒã
ç§ãã¡ã®ã»ãšãã©ã¯Nodeã䜿çšããŠWebã¢ããªã±ãŒã·ã§ã³ãäœæããŸããåŸæ¥ã®ïŒãµãŒããŒåŽïŒãŸãã¯REST APIã«åºã¥ããŠããŸãïŒã¯ã©ã€ã¢ã³ãåŽïŒã HTTPãªã¯ãšã¹ãã¯ã©ãã§ããïŒ ã¹ããªãŒãã³ã°ã§ããŸããïŒ ééããªãïŒ
èŠæ±ãšå¿çã¯ãã€ãã³ããšããã¿ãŒããç¶æ¿ãããèªã¿åãããã³æžã蟌ã¿ã¹ããªãŒã ã§ãã
data
ã€ãã³ãã¬ã·ãŒããŒãæ¥ç¶ããã³ãŒã«ããã¯ã§
chunk
ãåãå
¥ããããšãã§ããŸãã
chunk
ã¯ãå¿çå
šäœãåŸ
ããã«ããã«å€æã§ããŸãã 次ã®äŸã§ã¯ã
body
ãé£çµãã
end
ã€ãã³ãã®ã³ãŒã«ããã¯ã«è§£æããŸãã
const http = require('http') var server = http.createServer( (req, res) => { var body = '' req.setEncoding('utf8') req.on('data', (chunk) => { body += chunk }) req.on('end', () => { var data = JSON.parse(body) res.write(typeof data) res.end() }) }) server.listen(1337)
泚ïŒES6ã«ãããšã
()=>{}
ã¯å¿åé¢æ°ã®æ°ããæ§æã§ããã
const
ã¯æ°ããæŒç®åã§ãã ES6 / ES2015ã®æ©èœãšæ§æã«ãŸã æ
£ããŠããªãå Žåã¯ã
å¿ããJavaScriptéçºè
ãç¥ã£ãŠããã¹ãES6ããããã£ã«é¢ããããã10ã®èšäº
ãã芧
ãã ãã ã
次ã«ãExpress.jsã䜿çšããŠããµãŒããŒãå®éã®ç掻ããé¢ããªãããã«ããŸãã 巚倧ãªç»åïŒçŽ8 MBïŒãš2çµã®Expressã«ãŒã
/stream
ããã³
/non-stream
ã
server-stream.jsïŒ
app.get('/non-stream', function(req, res) { var file = fs.readFile(largeImagePath, function(error, data){ res.end(data) }) }) app.get('/stream', function(req, res) { var stream = fs.createReadStream(largeImagePath) stream.pipe(res) })
ãŸããã€ãã³ãã䜿çšãã
/stream2
代æ¿å®è£
ãšã
/non-stream2
åæå®è£
ããããŸãã ãããã¯åãããšãããŸãããç°ãªãæ§æãšã¹ã¿ã€ã«ã䜿çšããŸãã ãã®å Žåãè€æ°ã®ç«¶åãããªã¯ãšã¹ãã§ã¯ãªãã1ã€ã®ãªã¯ãšã¹ãã®ã¿ãéä¿¡ãããããåæã¡ãœããã®æ¹ãé«éã§ãã
ã¿ãŒããã«ãããã®ã³ãŒããå®è¡ã§ããŸãã
$ node server-stream
次ã«ãChrome
httpïŒ// localhostïŒ3000 / streamããã³
httpïŒ// localhostïŒ3000 / non-streamã§éã
ãŸã ã
X-Response-Time
æ¯èŒããŠãéçºè
ããŒã«ã®[ãããã¯ãŒã¯]ã¿ãã®ããããŒã«æ³šç®ããŠãã ããã ç§ã®å Žåã
/stream
ãš
/stream2
ã¯ãæ¡éãã«300ããªç§ç°ãªããŸããã 3-5ç§ å€ãç°ãªãå ŽåããããŸãããèãæ¹ã¯æ確ã§ãã/streamã®å Žå
/stream
ãŠãŒã¶ãŒ/ã¯ã©ã€ã¢ã³ãã¯ããæ©ãããŒã¿ãåä¿¡ãå§ããŸãã Nodeã§ã®ã¹ããªãŒãã³ã°ã¯éåžžã«åŒ·åãªããŒã«ã§ãïŒ ããŒã ã®ãã®åéã®å°é家ã«ãªãããšã§ãã¹ããªãŒã ãªãœãŒã¹ãé©åã«ç®¡çããæ¹æ³ãåŠã¶ããšãã§ããŸãã
npmã䜿çšãããšã
Stream Handbookãš
stream-adventureãã€ã³ã¹ããŒã«ã§ããŸãã
$ sudo npm install -g stream-adventure $ stream-adventure
ãããã¡
ãã€ããªããŒã¿ã«ã¯ã©ã®åã䜿çšã§ããŸããïŒ èŠããŠããã°ãJavaScriptãã©ãŠã¶ãŒã«ã¯ãã€ããªããŒã¿åã¯ãããŸããããNodeã«ã¯ãããŸãã ããã¯ãããã¡ãšåŒã°ããŸãã ããã¯ã°ããŒãã«ãªããžã§ã¯ããªã®ã§ãã¢ãžã¥ãŒã«ãšããŠã€ã³ããŒãããå¿
èŠã¯ãããŸããã
次ã®åŒã®ããããã䜿çšããŠããã€ããªã¿ã€ããäœæã§ããŸãã
new Buffer(size)
new Buffer(array)
new Buffer(buffer)
new Buffer(str[, encoding])
ã¡ãœãããšãšã³ã³ãŒãã£ã³ã°ã®å®å
šãªãªã¹ãã¯ã
ãããã¡ã®ããã¥ã¡ã³ãã§å
¥æã§ã
ãŸã ã æãäžè¬çã«äœ¿çšããã
utf8
ãšã³ã³ãŒãã£ã³ã°ã
éåžžããããã¡ã®å
容ã¯ã¡ãã€ãã®ããã«èŠããã®ã§ã人ãèªããããã«ããã«ã¯ããŸã
toString()
ã䜿çšããŠæååè¡šçŸã«å€æããå¿
èŠããããŸãã
for
ã«ãŒãã䜿çšããŠã¢ã«ãã¡ãããã§ãããã¡ãäœæ
for
ãŸãã
let buf = new Buffer(26) for (var i = 0 ; i < 26 ; i++) { buf[i] = i + 97
ãããã¡ãæååè¡šçŸã«å€æããªãå Žåãæ°å€ã®é
åã®ããã«ãªããŸãã
console.log(buf)
å€æãå®è¡ããŸãã
buf.toString('utf8')
æååã®äžéšïŒãµãæååïŒã®ã¿ãå¿
èŠãªå Žåãã¡ãœããã¯ç®çã®ã»ã°ã¡ã³ãã®åæçªå·ãšæçµäœçœ®ãååŸããŸãã
buf.toString('ascii', 0, 5)
fs
èŠããŠããŸããïŒ ããã©ã«ãã§ã¯ã
data
ããããã¡ãŒã§ãã
fs.readFile('/etc/passwd', function (err, data) { if (err) return console.error(err) console.log(data) });
data
ã¯ããã¡ã€ã«ãæäœãããšãã«ãããã¡ãŒãšããŠæ©èœããŸãã
ã¯ã©ã¹ã¿ãŒ
Nodeã®å察è
ã¯ãã¹ã¬ããã1ã€ãããªããããã¹ã±ãŒãªã³ã°ã§ãããšãã°ãã°äž»åŒµããŸãã ãã ããã¡ã€ã³
cluster
ã¢ãžã¥ãŒã«ã䜿çšãããšïŒã€ã³ã¹ããŒã«ããå¿
èŠã¯ãããŸãããããã¯ãã©ãããã©ãŒã ã®äžéšã§ãïŒãä»»æã®ãã·ã³ã®ãã¹ãŠã®ããã»ããµãªãœãŒã¹ã䜿çšã§ããŸãã ã€ãŸããã¯ã©ã¹ã¿ãŒã®ãããã§ãNodeã¢ããªã±ãŒã·ã§ã³ãåçŽæ¹åã«ã¹ã±ãŒãªã³ã°ã§ããŸãã
ã³ãŒãã¯éåžžã«ç°¡åã§ããã¢ãžã¥ãŒã«ãã€ã³ããŒããã1ã€ã®ãã¹ã¿ãŒãšè€æ°ã®ã¯ãŒã«ãŒãäœæããŸãã éåžžãCPUããšã«1ã€ã®ããã»ã¹ãäœæããŸãããããã¯æºãããªãèŠåã§ã¯ãããŸããã å¿
èŠãªæ°ã®ããã»ã¹ãå®è¡ã§ããŸãããåçæ§ãäœäžãããæ³åŸã«åŸã£ãŠãç¹å®ã®æç¹ããçç£æ§ã®æé·ãåæ¢ããŸãã
ãã¹ã¿ãŒã³ãŒããšåŸæ¥å¡ã³ãŒãã¯1ã€ã®ãã¡ã€ã«ã«ãããŸãã åŸæ¥å¡ã¯ãã€ãã³ãããã¹ã¿ãŒã«éä¿¡ããããšã«ãããåãããŒãã§ãªãã¹ã³ã§ããŸãã ãŠã£ã¶ãŒãã¯ã€ãã³ãããªãã¹ã³ããå¿
èŠã«å¿ããŠã¯ã©ã¹ã¿ãŒãåèµ·åã§ããŸãã ãŠã£ã¶ãŒãã§ã¯
cluster.isMaster()
ããã¯ãŒã«ãŒã§
cluster.isMaster()
ãŸãã ã»ãšãã©ã®ãµãŒããŒã³ãŒãã¯ã¯ãŒã«ãŒïŒ
isWorker()
ïŒã«é
眮ãããŸãã
ãã®äŸã§ã¯ããµãŒããŒãããã»ã¹IDãçºè¡ãããããããŸããŸãªã¯ãŒã«ãŒãããŸããŸãªèŠæ±ãåŠçããæ¹æ³ã確èªã§ããŸãã ããŒããã©ã³ãµãŒã®ããã«èŠããŸãããè² è·ã¯åçã«åæ£ãããªããããããã¯åãªãå°è±¡ã§ãã ããšãã°ãPIDã«ãããããã»ã¹ã®1ã€ãããå€ãã®èŠæ±ãåŠçããæ¹æ³ã確èªã§ããŸãã
, ,
loadtest
Node:
loadtest
npm: $ npm install -g loadtest
code/cluster.js
node ( $ node cluster.js
); .- :
$ loadtest http://localhost:3000 -t 20 -c 10
. loadtest
.- Ctrl+C. PID.
loadtest
-t 20 -c 10
, 10 20 .
â , . , . :
strong-cluster-control
(https://github.com/strongloop/strong-cluster-control) $ slc run
pm2
(https://github.com/Unitech/pm2)
pm2
pm2
, Node-. ,
pm2
production.
pm2
:
https://github.com/Unitech/pm2 http://pm2.keymetrics.io .
pm2 -
server.js
. ,
isMaster()
, ,
cluster
.
pid
.
var express = require('express') var port = 3000 global.stats = {} console.log('worker (%s) is now listening to http://localhost:%s', process.pid, port) var app = express() app.get('*', function(req, res) { if (!global.stats[process.pid]) global.stats[process.pid] = 1 else global.stats[process.pid] += 1; var l ='cluser ' + process.pid + ' responded \n'; console.log(l, global.stats) res.status(200).send(l) }) app.listen(port)
pm2 start server.js
. /, (
-i 0
, , , 4).
-l log.txt
:
$ pm2 start server.js -i 0 -l ./log.txt
, pm2 . :
$ pm2 list
loadtest
,
cluster
. :
$ loadtest http://localhost:3000 -t 20 -c 10
,
log.txt
- :
cluser 67415 responded { '67415': 4078 } cluser 67430 responded { '67430': 4155 } cluser 67404 responded { '67404': 4075 } cluser 67403 responded { '67403': 4054 }
Spawn, Fork Exec
cluter.js
Node-
fork()
. , Node.js :
spawn()
,
fork()
exec()
.
child_process
. :
require('child_process').spawn()
: ; stream'; ; V8.require('child_process').fork()
: V8 ; Node.js ( node
).require('child_process').exec()
: , ; , callback'; , node
.
:
node program.js
, â bash, Python, Ruby .. , ,
spawn()
.
data
stream':
var fs = require('fs') var process = require('child_process') var p = process.spawn('node', 'program.js') p.stdout.on('data', function(data)) { console.log('stdout: ' + data) })
node program.js
,
data
, , .
fork()
spawn()
, : ,
fork()
, Node.js:
var fs = require('fs') var process = require('child_process') var p = process.fork('program.js') p.stdout.on('data', function(data)) { console.log('stdout: ' + data) })
,
exec()
. , , callback. error, standard output :
var fs = require('fs') var process = require('child_process') var p = process.exec('node program.js', function (error, stdout, stderr) { if (error) console.log(error.code) })
error
stderr
,
exec()
(,
program.js
), â (,
program.js
).
Node.js
try/catch
. .
try { throw new Error('Fail!') } catch (e) { console.log('Custom Error: ' + e.message) }
, . Java
Node. Node.js
, thread.
, , /. , .
,
setTimeout()
, callback'. , HTTP-, :
try { setTimeout(function () { throw new Error('Fail!') }, Math.round(Math.random()*100)) } catch (e) { console.log('Custom Error: ' + e.message) }
callback ,
try/catch
. , callback
try/catch
, , . .
try/catch
.
, . ? , callback'
error
. : callback' .
if (error) return callback(error)
:
- (on error).
uncaughtException
.domain
( ) AsyncWrap .- .
- ( ).
- .
on('error')
on('error')
, Node.js,
http
.
error
, Express.js, LoopBack, Sails, Hapi ..,
http
.
js server.on('error', function (err) { console.error(err) console.error(err) process.exit(1) })
uncaughtException
uncaughtException
process
!
uncaughtException
â . , â Node.js â .
An unhandled exception means your application â and by extension Node.js itself â is in an undefined state. , .
process.on('uncaughtException', function (err) { console.error('uncaughtException: ', err.message) console.error(err.stack) process.exit(1) })
ãŸãã¯
process.addListener('uncaughtException', function (err) { console.error('uncaughtException: ', err.message) console.error(err.stack) process.exit(1)
ãã¡ã€ã³
domain
. Node.js . , . :
domain
callback'
run()
:
var domain = require('domain').create() domain.on('error', function(error){ console.log(error) }) domain.run(function(){ throw new Error('Failed!') })
4.0
domain
, Node . Node
domain
. , ,
domain
npm-, npm.
domain
.
setTimeout()
:
!
domain
error
âCustom Errorâ, Node .
C++
Node , IoT, , , /++. /++ ?
. Node , ++! , .
hello.cc
, . , .
#include <node.h> namespace demo { using v8::FunctionCallbackInfo; using v8::HandleScope; using v8::Isolate; using v8::Local; using v8::Object; using v8::String; using v8::Value; void Method(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = args.GetIsolate(); args.GetReturnValue().Set(String::NewFromUtf8(isolate, "capital one")); // String } void init(Local<Object> exports) { NODE_SET_METHOD(exports, "hello", Method); // Exporting } NODE_MODULE(addon, init) }
, , , JavaScript.
capital one
:
args.GetReturnValue().Set(String::NewFromUtf8(isolate, "capital one"));
hello
:
void init(Local<Object> exports) { NODE_SET_METHOD(exports, "hello", Method); }
hello.cc
, .
binding.gyp
, :
{ "targets": [ { "target_name": "addon", "sources": [ "hello.cc" ] } ] }
binding.gyp
hello.cc
,
node-gyp :
$ npm install -g node-gyp
,
hello.cc
binding.gyp
, :
$ node-gyp configure $ node-gyp build
build
.
build/Release/
.node
. , Node.js
hello.js
, C++:
var addon = require('./build/Release/addon') console.log(addon.hello())
capital one
, :
$ node hello.js
C++ :
https://github.com/nodejs/node-addon-examples .
ãããã«
GitHub . Node.js, callback' Node-,
Node: callback' observer' .
:
- : , / Node.
- : .
- : âobserverâ Node.js.
- : .
- : .
- : .
- Domain: .
- C++: .
Node JavaScript, , , , . , Node.js.