Reaktorã¯ãããã°ã§ãåŸæ¥å¡Petka AntonovïŒPetka AntonovïŒã«ãã£ãŠäœæãããBluebird Promisesã©ã€ãã©ãªã§äœ¿çšãããJavaScriptã³ãŒãæé©åã®ååãšäŸãå
±æããŸããã
Bluebirdã¯ã人æ°ã®ããJavaScript Promiseã©ã€ãã©ãªã§ãã 2013å¹Žã«æåã«æ°ã¥ãããã®ã¯ãåæ§ã®ããããã£ã»ãããåããä»ã®Promiseså®è£
ãæå€§100åäžåãããšã倿ãããšãã§ãã JavaScriptã®åºæ¬çãªæé©åååã®ããã€ããäžè²«ããŠé©çšããŠãããããBluebirdã¯éåžžã«é«éã§ãã ãã®èšäºã§ã¯ãBluebirdã®æé©åã«äœ¿çšããã3ã€ã®æãéèŠãªååã«ã€ããŠè©³ãã説æããŸãã
1.æ©èœã®äœæãæå°éã«æãã
ãªããžã§ã¯ãã®äœæãç¹ã«é¢æ°ãªããžã§ã¯ãã®äœæïŒ 翻蚳è
æ³šïŒ ãã¹ãŠã®é¢æ°ã¯ãªããžã§ã¯ãã§ã ïŒ ã¯ã倧éã®å
éšããŒã¿ã䜿çšããå¿
èŠããããããããã©ãŒãã³ã¹ã®ç¹ã§éåžžã«ã³ã¹ããããããŸãã å®éã®JavaScriptå®è£
ã«ã¯ã¬ããŒãžã³ã¬ã¯ã¿ãŒãå«ãŸããŠããŸããã€ãŸããäœæããããªããžã§ã¯ãã¯ã¡ã¢ãªå
ã«çãŸãããšã¯ãããŸãããã¬ããŒãžã³ã¬ã¯ã¿ãŒã¯æªäœ¿çšã®ãªããžã§ã¯ããåžžã«æ€çŽ¢ããŠãå æããŠããã¡ã¢ãªãè§£æŸããŸãã JavaScriptã§äœ¿çšããã¡ã¢ãªãå€ãã»ã©ãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã«ãããCPUãå€ããªããã³ãŒãèªäœãæ©èœããããã«æ®ãããéãå°ãªããªããŸãã JavaScriptã§ã¯ã颿°ã¯ãã¡ãŒã¹ãã¯ã©ã¹ãªããžã§ã¯ãã§ã ã ããã¯ãä»ã®ãªããžã§ã¯ããšåãæ©èœãšããããã£ãæã£ãŠããããšãæå³ããŸãã å¥ã®é¢æ°ã®å®£èšãå«ã颿°ãããå Žåãå
ã®é¢æ°ãåŒã³åºããã³ã«ãåãããšãè¡ãæ°ããäžæã®é¢æ°ãäœæãããŸãã ç°¡åãªäŸãèããŠã¿ãŸãããã
function trim(string) { function trimStart(string) { return string.replace(/^\s+/g, ""); } function trimEnd(string) { return string.replace(/\s+$/g, ""); } return trimEnd(trimStart(string)) }
trim
ãåŒã³åºããããã³ã«ã trimStart
ãštrimEnd
ã衚ã2ã€ã®é¢æ°ãªããžã§ã¯ããäœæãããŸãã ãã ããããããã£ã®å²ãåœãŠãªã©ã®ãªããžã§ã¯ãåºæã®åäœã倿°ã®éå
ã䜿çšããªãããããããã¯å¿
èŠãããŸããã ãããã䜿çšãããå¯äžã®çç±ã¯ãå«ãŸããã³ãŒãã®æ©èœã®ããã§ãã
ãã®äŸã¯ç°¡åã«æé©åã§ããŸã-颿°ãtrim
ããåãåºãã ãã§ãã ãã®äŸã¯ã¢ãžã¥ãŒã«ã«å«ãŸããŠãããã¢ãžã¥ãŒã«ã¯ããã°ã©ã ã«äžåºŠããŒããããããã颿°ã®å Žåã衚çŸã¯1ã€ã ãã§ãã
function trimStart(string) { return string.replace(/^\s+/g, ""); } function trimEnd(string) { return string.replace(/\s+$/g, ""); } function trim(string) { return trimEnd(trimStart(string)) }
ãã ããã»ãšãã©ã®å Žåãæ©èœã¯å¿
èŠãªæªã®ããã«èŠããŸããããããåãé€ãããšã¯ã§ããŸããã ããšãã°ãé
å»¶ã³ãŒã«ã®ã³ãŒã«ããã¯é¢æ°ãæž¡ããã³ã«ãã³ãŒã«ããã¯ã«ã¯äžæã®ã³ã³ããã¹ããå¿
èŠã§ãã éåžžãã³ã³ããã¹ãã¯ãã¯ããŒãžã£ãŒã䜿çšããããšã«ãããã·ã³ãã«ã§çŽæçã§ããéå¹ççãªæ¹æ³ã§å®è£
ãããŸãã ç°¡åãªäŸãšããŠãæšæºã®éåæã³ãŒã«ããã¯ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠãJSONããããŒãã«ãã¡ã€ã«ãèªã¿åããŸãã
var fs = require('fs'); function readFileAsJson(fileName, callback) { fs.readFile(fileName, 'utf8', function(error, result) { // readFileAsJson. // , Context // . if (error) { return callback(error); } // try-catch // - JSON try { var json = JSON.parse(result); callback(null, json); } catch (e) { callback(e); } }) }
ãã®äŸã§ã¯ã fs.readFile
æž¡ãããã³ãŒã«ããã¯ã¯ãäžæã®callback
倿°ã®åšãã«ã¯ããŒãžã£ãŒãäœæããããã readFileAsJson
ããfs.readFile
ããšãã§ããŸããã ååä»ã颿°ã«å¿åã®ã³ãŒã«ããã¯ã詊ã¿ãŠãäœãèµ·ãããªãããšã«æ³šæããŠãã ããã
Bluebirdå
ã§åžžã«äœ¿çšãããæé©åã¯ãæç€ºçãªåçŽãªãªããžã§ã¯ãã䜿çšããŠã³ã³ããã¹ãããŒã¿ãä¿æããããšã§ãã å€ãã®ã¬ãã«ã§ã³ãŒã«ããã¯ã転éããã«ã¯ããã®ãããªãªããžã§ã¯ãã®1ã€ã ãã«ã¡ã¢ãªãå²ãåœãŠãå¿
èŠããããŸãã åã¬ãã«ã§æ°ããã¯ããŒãžã£ãŒãäœæãã代ããã«ãã³ãŒã«ããã¯ã次ã®ã¬ãã«ã«æž¡ããããšãã«ã远å ã®åŒæ°ã䜿çšããŠæç€ºçãªåçŽãªãªããžã§ã¯ããæž¡ããŸãã ããšãã°ãå
ã®é¢æ°ã«5ã€ã®ã¬ãã«ãããå Žåãã¯ããŒãžã£ãŒã䜿çšãããšã5ã€ã®é¢æ°ãšContextãªããžã§ã¯ããããããšå
±ã«äœæãããããšãæå³ããŸãã ãã®æé©åã®å Žåããããã®ç®çã®ããã«1ã€ã®ãªããžã§ã¯ãã®ã¿ãäœæãããŸãã
fs.readFile
ã倿ŽããŠã³ã³ããã¹ããªããžã§ã¯ããæž¡ãããšãã§ããå Žåãæé©åã¯æ¬¡ã®ããã«é©çšã§ããŸãã
var fs = require('fs-modified'); function internalReadFileCallback(error, result) { // readFile callback , // `this`, // if (error) { return this(error); } // try-catch // - JSON try { var json = JSON.parse(result); this(null, json); } catch (e) { this(e); } } function readFileAsJson(fileName, callback) { // fs.readFile . // , callback, // fs.readFile(fileName, 'utf8', internalReadFileCallback, callback); }
ãã¡ãããAPIã®äž¡æ¹ã®éšåãå¶åŸ¡ããå¿
èŠããããŸã-ã³ã³ããã¹ããã©ã¡ãŒã¿ãŒã®ãµããŒããªãã§ã¯ããã®ãããªæé©åã¯é©çšã§ããŸããã ãã ããããã䜿çšããå ŽåïŒããšãã°ãå€ãã®å
éšã¬ãã«ãå¶åŸ¡ããå ŽåïŒãããã©ãŒãã³ã¹ã®åäžã¯é¡èã§ãã ããŸãç¥ãããŠããªãäºå®ïŒ Array.prototype.forEach
ãªã©ã®äžéšã®çµã¿èŸŒã¿JavaScript Array APIã¯ã2çªç®ã®ãã©ã¡ãŒã¿ãŒãšããŠã³ã³ããã¹ããªããžã§ã¯ããArray.prototype.forEach
ãŸãã
2.ãªããžã§ã¯ãã®ãµã€ãºãæå°åããŸã
é »ç¹ã«äœæããããªããžã§ã¯ããšãPromiseãªã©ã®å€§éã«äœæããããªããžã§ã¯ãã®ãµã€ãºãæå°éã«æããããšãéèŠã§ãã ã»ãšãã©ã®JavaScriptå®è£
ã§ãªããžã§ã¯ããäœæãããããŒãã¯ãå æé åãšç©ºãé åã«åããããŸãã å°ãããªããžã§ã¯ãã¯å€§ãããªããžã§ã¯ããããé·ã空ãã¹ããŒã¹ãåãããã®çµæãã¬ããŒãžã³ã¬ã¯ã¿ãŒã®äœæ¥ãå°ãªããªããŸãã ãŸããéåžžãå°ããªãªããžã§ã¯ãã«ã¯å«ãŸãããã£ãŒã«ããå°ãªãã®ã§ãã¬ããŒãžã³ã¬ã¯ã¿ãŒã¯ãããã®åšããç°¡åã«ç§»åããŠãã©ã€ããªããžã§ã¯ããšããããªããžã§ã¯ããããŒã¯ããŸãã
ããŒã«ããã³/ãŸãã¯å¶éãããæ°ã®ãã£ãŒã«ãã¯ã ãããåäœã®æäœã«ãã£ãŠããã«å§çž®ãããŸã ã JavaScriptã®ãããæŒç®ã¯ã32ãããã®æ°å€ã§æ©èœããŸãã 1ã€ã®ãã£ãŒã«ãã«ã¯ã32åã®ããŒã«ãã£ãŒã«ãã8åã®4ãããæ°ã16åã®ããŒã«å€ãš2åã®8ãããæ°ãªã©ãé
眮ã§ããŸããã³ãŒããèªã¿ãããããã«ã¯ãåè«çãã£ãŒã«ãã«å¿
èŠãªãããæŒç®ãå®è¡ããã²ãã¿ãŒãšã»ãã¿ãŒãå¿
èŠã§ãç©ççãªæå³ã 1ã€ã®ããŒã«åãã£ãŒã«ããæ°å€ã«å§çž®ããæ¹æ³ã®äŸã次ã«ç€ºããŸãïŒä»ã®è«çãã£ãŒã«ãçšã«ããã«å±éã§ããŸãïŒã
// 1 << 1 , 1 << 2 .. const READONLY = 1 << 0; class File { constructor() { this._bitField = 0; } isReadOnly() { // . return (this._bitField & READONLY) !== 0; } setReadOnly() { this._bitField = this._bitField | READONLY; } unsetReadOnly() { this._bitField = this._bitField & (~READONLY); } }
ã¢ã¯ã»ã¹ã¡ãœããã¯éåžžã«çãã®ã§ãã»ãšãã©ã®å Žåã远å ã®é¢æ°åŒã³åºããªãã§ã©ã³ã¿ã€ã ã«çµã¿èŸŒãŸããŸãã
翻蚳è
ã®ã¡ã¢ïŒ JavaScriptã³ã³ãã€ã©ãŒã®æäœã«é¢ããåºæ¬æ
å ±ãã€ã³ã©ã€ã³ãã£ãã·ã³ã°ãšåã蟌ã¿é¢æ°ã®æŠå¿µã«ã€ããŠã¯ãèšäºã JavaScriptã³ã³ãã€ã«ã®éå»ãšæªæ¥ããåç
§ããŠãã ããã ãªããã£ãã€ã¶ãŒã®åäœã«ã€ããŠ-Petka Antonovã«ããæé©åãã©ãŒ ïŒãªãªãžãã«ã®æŽæ°ããããŸãïŒããã³Optimization Killerã®ç¿»èš³ïŒ2014幎ã«å
¬éïŒã
åæã«äœ¿çšãããªã2ã€ä»¥äžã®ãã£ãŒã«ãã¯ããã£ãŒã«ãã«é
眮ãããå€ã®ã¿ã€ãã远跡ãããã©ã°ã䜿çšããŠ1ã€ã®ãã£ãŒã«ãã«å§çž®ã§ããŸãã ãã ããäžèšã®ããã«ããã©ã°ãå§çž®ãããæ°å€ãšããŠå®è£
ãããŠããå Žåã«ã®ã¿ããã®ã¡ãœããã¯ã¹ããŒã¹ãç¯çŽããŸãã
Bluebirdã§ã¯ããã®ããªãã¯ã䜿çšããŠãçŽæã®äŸ¡å€ãŸãã¯æåŠã®çç±ãä¿æããŸãã ããã«ã¯å¥ã®ãã£ãŒã«ãã¯ãããŸãããçŽæãæºããããå Žåãå®è¡ã®çµæã¯æåŠã³ãŒã«ããã¯ã®ãã£ãŒã«ãã«æ ŒçŽãããçŽæãæåŠãããå ŽåãæåŠã®çç±ã¯æåå¿çã³ãŒã«ããã¯ãã£ãŒã«ãã«ä¿åãããŸãã ç¹°ãè¿ããŸãããå€ãžã®ã¢ã¯ã»ã¹ã¯ãå®è£
ã®è©³çްãé ãã¢ã¯ã»ã¹é¢æ°ãä»ããŠè¡ãå¿
èŠããããŸãã
ãªããžã§ã¯ãã«ãšã³ãã£ãã£ã®ãªã¹ããä¿åããå¿
èŠãããå Žåã¯ããªããžã§ã¯ãã®ã€ã³ããã¯ã¹ä»ãããããã£ã«å€ãçŽæ¥ä¿åããããšã«ãããåå¥ã®é
åã®äœæãåé¿ã§ããŸãã æžã代ããã«ïŒ
class EventEmitter { constructor() { this.listeners = []; } addListener(fn) { this.listeners.push(fn); } }
é
åãé¿ããããšãã§ããŸãïŒ
class EventEmitter { constructor() { this.length = 0; } addListener(fn) { var index = this.length; this.length++; this[index] = fn; } }
.length
ãã£ãŒã«ããå°ããªæ°ã«å¶éã§ããå ŽåïŒããšãã°ã10ããããã€ãŸãã event emitter
ã¯æå€§1024人ã®ãªã¹ããŒãæã€ããšãã§ããŸãïŒãä»ã®å¶éãããæ°ãšããŒã«å€ãå«ãããããã£ãŒã«ãã®äžéšã«ããããšãã§ããŸãã
3. no-op颿°ã䜿çšããŸãã é«äŸ¡ãªãªãã·ã§ã³æ©èœãå®è£
ããããã«ããããé
å»¶çã«æžãæããŸã
Bluebirdã«ã¯ãäœ¿çšæã«ã©ã€ãã©ãªå
šäœã®ããã©ãŒãã³ã¹ãåäžã«äœäžãããããã€ãã®ãªãã·ã§ã³æ©èœãå«ãŸããŠããŸãã ãããã¯ãvoringsãã¹ã¿ãã¯ãã¬ãŒã¹ããã£ã³ã»ã«ããæ©èœãPromise.prototype.bindãpromiseã®ã¹ããŒã¿ã¹ã®ç£èŠãªã©ã§ãã ãããã®é¢æ°ã«ã¯ãã©ã€ãã©ãªå
šäœã§ã€ã³ã¿ãŒã»ãã¿ãŒåŒã³åºããå¿
èŠã§ãã ããšãã°ãPromiseç£èŠæ©èœã§ã¯ãPromiseãäœæãããã³ã«ã€ã³ã¿ãŒã»ãã¿ãŒãåŒã³åºãå¿
èŠããããŸãã
å®éã®ç¶æ
ã«é¢ä¿ãªããæ¯åç£èŠæ©èœãèµ·åããããããç£èŠæ©èœããªã³ã«ãªã£ãŠãããã©ãããåŒã³åºãåã«ç¢ºèªããæ¹ãã¯ããã«ç°¡åã§ãã ãã ããã€ã³ã©ã€ã³ãã£ãã·ã¥ïŒ 翻蚳è
ã®ã¡ã¢ïŒãããã¯ã«é¢ããå¥ã®ã¡ã¢ ïŒãšæ©èœã®çµ±åã®ãããã§ããã®æäœã¯ç£èŠãç¡å¹ã«ããŠãããŠãŒã¶ãŒã«å¯ŸããŠå®å
šã«ç°¡çŽ åã§ããŸãã ãããè¡ãã«ã¯ã空ã®é¢æ°ãå
ã®ã€ã³ã¿ãŒã»ãã¿ãŒã¡ãœããã«å²ãåœãŠãŸãã
class Promise { // ... constructor(executor) { // ... this._promiseCreatedHook(); } // no-op . _promiseCreatedHook() {} }
çŸåšããŠãŒã¶ãŒãç£èŠæ©èœãæå¹ã«ããŠããªãå Žåããªããã£ãã€ã¶ãŒã¯ã€ã³ã¿ãŒã»ãã¿ãŒãäœãããŠããªãããšã確èªãããããç°¡çŽ åããŸãã ã³ã³ã¹ãã©ã¯ã¿ãŒã«ã€ã³ã¿ãŒã»ãã¿ãŒã¡ãœãããååšããªãããšãããããŸãã
ç£èŠæ©èœãæ©èœããããã«ã¯ãç£èŠæ©èœãå«ãããšãé¢é£ãããã¹ãŠã®no-opæ©èœãå®éã®å®è£
ã«äžæžããããŸãã
function enableMonitoringFeature() { Promise.prototype._promiseCreatedHook = function() {
ãã®ãããªã¡ãœããã®æžãæãã«ãããPromiseã¯ã©ã¹ã®ãªããžã§ã¯ãçšã«äœæãããã€ã³ã©ã€ã³ãã£ãã·ã¥ãç¡å¹ã«ãªããŸãã ããã¯ãçŽæãäœæãããåã«ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åæã«è¡ãå¿
èŠããããŸãã ãããã£ãŠããã®åŸã«äœæãããã€ã³ã©ã€ã³ãã£ãã·ã¥ã¯ãno-op颿°ãååšããããšãèªèããŸããã
ãªãªãžãã«ïŒPetka Antonovã«ããBluebirdãé«éã«ãã3ã€ã®JavaScriptããã©ãŒãã³ã¹ã®åºç€ ã
ç¿»èš³ïŒ aalexeev ã æ¹èšè
ïŒ jabher ã