Developer Softã®ãœãããŠã§ã¢ãšã³ãžãã¢ã§ã Netologyã³ãŒã¹ã®æåž«ã§ããVladislav Vlasovã¯ãããã°å°çšã®EcmaScript6ã«é¢ããäžé£ã®èšäºãå·çããŸããã 第1éšã§ã¯ ãäŸã¯Iroh.jsã䜿çšããŠEcmaScriptã®åçã³ãŒãåæã調ã¹ãŸããã ãã®èšäºã§ã¯ããã£ã³ã»ã«ãããPromiseãå®è£
ããæ¹æ³ã瀺ããŸã ã
EcmaScriptã®éåæããã³ã€ãã³ãã¹ã±ãžã¥ãŒã©ãŒ
PromiseïŒçŽæïŒã®æŠå¿µã¯ãææ°ã®EcmaScriptã®éèŠãªèŠçŽ ã®1ã€ã§ãã Promiseã䜿çšãããšãéåæã¢ã¯ã·ã§ã³ããã§ãŒã³ã«ç·šæããããšã§éåæã¢ã¯ã·ã§ã³ã®äžè²«ããå®è¡ãä¿èšŒã§ããããã«ãšã©ãŒãã©ãããæäŸã§ããŸãã async / awaitã¹ããŒãã¡ã³ãã®ææ°ã®æ§æãæè¡çã«ã¯Promiseã«åºã¥ããŠãããåãªãæ§æäžã®ç ç³ã§ãã

ãã®ãã¹ãŠã®è±å¯ãªæ©èœã«ã€ããŠãPromiseã«ã¯1ã€ã®æ¬ ç¹ããããŸã-å®è¡äžã®ã¢ã¯ã·ã§ã³ããã£ã³ã»ã«ããæ©èœããµããŒãããŠããŸããã ãã®å¶éãåé¿ããæ¹æ³ãçè§£ããã«ã¯ãPromiseã¯ãããã®åãªãã©ãããŒã§ãããããéåæã¢ã¯ã·ã§ã³ãEcmaScriptã§ã©ã®ããã«çºçããæ©èœããããèæ
®ããå¿
èŠããããŸãã
EcmaScriptãšã³ãžã³ã¯ãV8ã§ããChakraã§ãããã·ã³ã°ã«ã¹ã¬ããã§ãããäžåºŠã«1ã€ã®ã¢ã¯ã·ã§ã³ã®ã¿ãèš±å¯ããŸãã ãã©ãŠã¶ãŒç°å¢ã§ã¯ãããªãææ°ã®ãšã³ãžã³ãWebWorkersãã¯ãããžãŒããµããŒãããŠãããNode.jsã§åå¥ã®åããã»ã¹ãäœæã§ããŸããããã«ãããã³ãŒãå®è¡ã䞊ååãããŸãã ãã ããäœæãããå®è¡ã¹ã¬ããã¯ãã¡ãã»ãŒãžãä»ããŠã®ã¿äœæããã¹ã¬ãããšæ
å ±ã亀æã§ããç¬ç«ããããã»ã¹ã§ãããããããèªäœã¯ãã«ãã¹ã¬ããã¢ãã«ã§ã¯ãããŸããã
代ããã«ãåŸæ¥ã®EcmaScriptã¯å€éåã¢ãã«ã«åºã¥ããŠããŸããè€æ°ã®ã¢ã¯ã·ã§ã³ã䞊è¡ããŠå®è¡ããããã«ãã¢ã¯ã·ã§ã³ã¯å°ããªãã©ã°ã¡ã³ãã«åå²ãããåãã©ã°ã¡ã³ãã¯æ¯èŒçè¿
éã«å®è¡ãããå®è¡ãããŒããããã¯ããŸããã ãã®ãããªãã©ã°ã¡ã³ããæ··åããããšã«ããããããã«é¢é£ä»ããããã¢ã¯ã·ã§ã³ã¯å®éã«äžŠè¡ããŠå®è¡ãããŸãã
ããšãã°ãWebããŒãžã®ããžã¥ã¢ã«ã€ã³ã¿ãŒãã§ã€ã¹ïŒUIïŒã®ã¬ã³ããªã³ã°ãªã©ã®ãŠãŒã¶ãŒã³ãŒããšãã¹ãç°å¢é¢æ°ã¯åãã¹ã¬ããã§å®è¡ãããããããŠãŒã¶ãŒã³ãŒãã®é·ãã«ãŒããŸãã¯ç¡éã«ãŒãã¯Webã®ã¬ã³ããªã³ã°ã®äžæåæ¢ã«ã€ãªãããŸããããŒãžãšãã®ããªãŒãºã ç¹å®ã®ã³ãŒããã©ã°ã¡ã³ããå®è¡ãããæéééãåé¢ããã«ã¯ãã€ãã³ãã¹ã±ãžã¥ãŒã©ãã€ãŸãã€ãã³ãã«ãŒãã䜿çšããŸãã å®è¡å¯èœãã©ã°ã¡ã³ãã¯ã€ãã³ãã«ãŒãã«ã©ã®ããã«è¡šç€ºãããŸããïŒ
éåžžã®ã¯ã©ã€ã¢ã³ãã³ãŒãã¯ãæ¡ä»¶ãã«ãŒããããã³é¢æ°åŒã³åºãã䌎ãå®è¡ã¹ã¬ããã§æ§æãããäžé£ã®ã¢ã¯ã·ã§ã³ã®ã¿ãå®è¡ããŸãã é
å»¶å®è¡ãå®è¡ããã«ã¯ããã¹ãç°å¢ã«ã¯ã©ã€ã¢ã³ãã³ãŒã«ããã¯é¢æ°ãç»é²ããå¿
èŠããããŸãã
ãã©ãŠã¶ãŒç°å¢ã§ã¯ãããã¯éåžžãã¿ã€ããŒãã€ãã³ããããã³ãªãœãŒã¹ã®éåæèŠæ±ã®3ã€ã®å¯èœæ§ã®ããããã«ãªããŸãã ã¿ã€ããŒã¯ãæéåŸïŒ
setTimeout
ïŒãã€ãã³ãã¹ã±ãžã¥ãŒã©ã®æåã®ç©ºãã¹ãããïŒ
setImmediate
ïŒããŸãã¯WebããŒãžã®ã¬ã³ããªã³ã°ããã»ã¹ïŒ
requestAnimationFrame
ïŒã§ã颿°åŒã³åºããæäŸããŸãã ã€ãã³ãã¯ãååãšããŠDOMã¢ãã«ã§è¡ãããã¢ã¯ã·ã§ã³ã«å¯Ÿããåå¿ã§ããããŠãŒã¶ãŒïŒã€ãã³ãïŒãã¿ã³ãã¯ãªãã¯ïŒãšUIèŠçŽ ã衚瀺ããå
éšããã»ã¹ïŒã€ãã³ãïŒã¹ã¿ã€ã«åã«ãŠã³ãå®äºïŒã®äž¡æ¹ã«ãã£ãŠããªã¬ãŒã§ããŸãã ãªãœãŒã¹èŠæ±ã¯å¥ã®ã«ããŽãªã«é
眮ãããŸãããå®éã«ã¯ã€ãã³ãã«é¢é£ããŠããŸãããå¯äžã®éãã¯å
ã®ã€ãã·ãšãŒã¿ãŒãã¯ã©ã€ã¢ã³ãã³ãŒããã®ãã®ã§ããããšã§ãã
ããã¯ã次ã®å³ã«æç¢ºã«ç€ºãããŠããŸãã

éåæã¢ã¯ã·ã§ã³ã©ãããŒ
ããã«ãäžèšã®éåæã¢ã¯ã·ã§ã³ãã©ã®ããã«Promiseã«å€ããããèæ
®ããããšãéèŠã§ãã Promiseããã£ã³ã»ã«ããããã®ã¢ã¹ãã¯ãã®æå€§æ°ã«å¯ŸåŠããããã«ã次ã®ã³ãŒãã¯ã¿ã€ããŒãDOMã¢ãã«ã€ãã³ããããã³ããããçµåããä»»æã®ã¯ã©ã€ã¢ã³ãã³ãŒãã®äœ¿çšãçµã¿åãããŸãã ãã®äŸã§ã¯ãCSV圢åŒã§å€§éã®ããŒã¿ãè¿ãAJAXãªã¯ãšã¹ããå®è¡ããã¡ã€ã³ã¹ã¬ãããããªãŒãºããã®ãé²ãããã«æœåšçã«äœéãªè¡åäœã®é¢æ°ã§åŠçããŸãã
function fetchInformation() { function parseRow(rawText) { } const xhrPromise = new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', '.../some.csv'); // API endpoint URL with some big CSV database xhr.onload = () => { if (xhr.status >= 200 && xhr.status < 300) { resolve(String(xhr.response)); } else { reject(new Error(xhr.status)); } }; xhr.onerror = () => { reject(new Error(xhr.status)); }; xhr.send(); }); const delayImpl = window.setImmediate ? setImmediate : requestAnimationFrame; const delay = () => new Promise(resolve => delayImpl(resolve)) const parsePromise = (response) => new Promise((resolve, reject) => { let flowPromise = Promise.resolve(); let lastDemileterIdx = 0; let result = []; while(lastDemileterIdx >= 0) { const newIdx = response.indexOf('\n', lastDemileterIdx); const row = response.substring( lastDemileterIdx, (newIdx > -1 ? newIdx - lastDemileterIdx : Infinity) ); flowPromise = flowPromise.then(() => { result.push(parseRow(row)); return delay(); }); lastDemileterIdx = newIdx; } flowPromise.then(resolve, reject); }); return xhrPromise.then(parsePromise); }
AJAXãªã¯ãšã¹ãã®æåãŸãã¯ãšã©ãŒå®äºã¯DOMã¢ãã«ã®ã€ãã³ããšããŠäœ¿çšãããã¿ã€ããŒã¯å€§éã®ããŒã¿ã®é 次ãããåŠçãæäŸããUIã¹ããªãŒã ã«äœæ¥æéãæäŸããŸãã å€éšã®èгç¹ããèŠããšããã®ãããªPromiseã¯ã¢ããªã·ãã¯ãªèŠçŽ ã§ããããã®æåŸã§é©åãªåœ¢åŒã®åŠçæžã¿ããŒã¿ããŒã¹ãåŒã³åºãå
ã«å©çšå¯èœã§ããããšããŸãã¯å®è¡äžã«é害ãçºçããå Žåã®ãšã©ãŒã®èª¬æã§ãã
çºä¿¡è
ã®èгç¹ããã¯ããã®ãããªPromiseå
šäœããã£ã³ã»ã«ã§ãããšäŸ¿å©ã§ãã ããšãã°ããŠãŒã¶ãŒããã®ããŒã¿ã衚瀺ããããã«å¿
èŠãªèŠèŠèŠçŽ ãéããå Žåã ãã ããå
éšæ§é ã®èгç¹ããèŠããšãPromiseã¯åæã¢ã¯ã·ã§ã³ãšéåæã¢ã¯ã·ã§ã³ã®ã»ããã§ããããã®äžéšã¯ãã§ã«èµ·åãããŠå®äºããŠããå ŽåããããŸãã ãã®ã·ãŒã±ã³ã¹ã¯ä»»æã®ã¯ã©ã€ã¢ã³ãã³ãŒãã«ãã£ãŠæ±ºå®ããããããç·æ¥å®äºæé ãæåã§èšè¿°ããå¿
èŠããããŸãã
ãã£ã³ã»ã«ãããçŽæã®å®è£
ã«ãŒããªã©ã®åæã³ãŒãã®äžæã¯ååçã«çºçããªãããšã«æ³šæããŠãã ãããã³ãŒããæ¢ã«å®è¡ãããŠããå ŽåïŒããã³EcmaScriptãšã³ãžã³ãã·ã³ã°ã«ã¹ã¬ããã§ããå ŽåïŒããããäžæããä»ã®ã³ãŒãã¯å®è¡ã§ããŸããã ãããã£ãŠãã¿ã€ããŒãã€ãã³ããããã³å€éšãªãœãŒã¹ãžã®åŒã³åºããªã©ãå®äºãå¿
èŠãªã®ã¯äžèšã®çã®éåæã¢ã¯ã·ã§ã³ã®ã¿ã§ãã
ã¿ã€ããŒèšå®é¢æ°ã«ã¯ããããããã£ã³ã»ã«ããããã®
clearTimeout
ã
clearImmediate
ã
cancelAnimationFrame
2ã€ã®æäœã
cancelAnimationFrame
ãŸãã DOMã¢ãã«ã®ã€ãã³ãã®å Žåã察å¿ããã³ãŒã«ããã¯é¢æ°ããåã«ãµãã¹ã¯ã©ã€ããè§£é€ããŸãã ãŸããã¿ã€ããŒã®å Žåã¯ãããç°¡åãªã¢ãããŒãã䜿çšã§ããŸã-æåã®
isCancelled
ãã©ã°ãæã€Promiseãªããžã§ã¯ãã§ããããäºåã«ã©ããããŸãã ã¿ã€ããŒã®æéãåããåŸãPromiseããã£ã³ã»ã«ããå¿
èŠãããå Žåãã³ãŒã«ããã¯é¢æ°ã¯åã«å®è¡ãããŸããã ãã®å Žåãã¿ã€ããŒã¯ã¹ã±ãžã¥ãŒã©ã«æ®ããŸããããã£ã³ã»ã«ããå ŽåãçµäºåŸã«äœãèµ·ãããŸããã
å€éšãªãœãŒã¹ã«ã¢ã¯ã»ã¹ããå Žåãç¶æ³ã¯ããè€éã§ãããããã®å Žåãã察å¿ããã€ãã³ãã®ãµãã¹ã¯ã©ã€ããè§£é€ããããšã§æäœã®çµæãç¡èŠã§ããŸãããæäœèªäœãäžæã§ãããšã¯éããŸããã Promiseã®å®è¡ããžãã¯ã®èгç¹ããã¯ãããã¯éèŠã§ã¯ãªããããããŸããããäžæãããªãæäœã¯äžå¿
èŠãªãªãœãŒã¹ãæ¶è²»ããŸãã
ç¹ã«ãAJAXãªã¯ãšã¹ããå®è¡ããããã®åŸæ¥ã®
XMLHttpRequest
ã眮ãæããããã«èšèšããã远å ã®ã©ãããŒãå¿
èŠãšããã«ããã«Promiseãªããžã§ã¯ããè¿ã
fetch
ã¡ãœããã§ã¯ããªã¯ãšã¹ãããã£ã³ã»ã«ã§ããŸããã ãã®ãããHTTPãªã¯ãšã¹ããå®éã«ãã£ã³ã»ã«ããã«ã¯ã
XMLHttpRequest
ãªããžã§ã¯ãã§
abort
ã¡ãœããã䜿çšããå¿
èŠããããŸãã
çµæã®Promiseãã£ã³ã»ã«ãµããŒãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã ããããããããããã«ã倿Žãããã³ãŒãã®ã¿ã衚瀺ãããå€ãã³ãŒãã¯çç¥èšå·ä»ãã®ã³ã¡ã³ãã«çœ®ãæããããŸãã
function fetchInformation() { let isCancelled = false; let xhrAbort; const xhrPromise = new Promise((resolve, reject) => { xhrAbort = xhr.abort.bind(xhr); }); const delayImpl = window.setImmediate ? setImmediate : requestAnimationFrame; const delay = () => new Promise((resolve, reject) => delayImpl(() => (!isCancelled ? resolve(): reject(new Error('Cancelled')))) ); const promise = xhrPromise.then(parsePromise); promise.cancel = () => { try { xhrAbort(); } catch(err) {}; isCancelled = true; } return promise; }
Promiseã¯EcmaScriptã®èгç¹ããèŠããšéåžžã®ãªããžã§ã¯ããªã®ã§ã
cancel
ã¡ãœãããç°¡åã«è¿œå ã§ããŸãã ãŸããçµæã®Promiseãªããžã§ã¯ãã1ã€ã ãå€éšç°å¢ã«è¿ãããããã
cancel
ã¡ãœããããã®ãªããžã§ã¯ãã«å¯ŸããŠã®ã¿è¿œå ããããã¹ãŠã®å
éšããžãã¯ãçæé¢æ°ã®çŸåšã®åå¥ãããã¯ã«ã«ãã»ã«åãããŸãã
ãŸãšã
EcmaScriptã§ãã£ã³ã»ã«ãããPromiseãå®è£
ããããšã¯ãå
éšã«é£ç¶ããåŒã³åºãã®éèªæãªããžãã¯ãããéåæãã§ãŒã³ã«å¯ŸããŠãç°¡åã«å®è¡ã§ããæ¯èŒçåçŽãªã¿ã¹ã¯ã§ãïŒãªããžã§ã¯ãã«ãã£ã³ã»ã«ãã©ã°ãä¿åãã颿°ãçæããã³ã³ããã¹ããã¢ã¯ãã£ãã«ããŸãã ãã£ã³ã»ã«ã¯ãPromiseããšã©ãŒã§äžæãããŠãµãŒãããŒãã£ã®å¹æãå®è¡ãããªãå Žåã®è¡šé¢çãªãã®ããŸãã¯éå§ããããã¹ãŠã®éåææäœïŒã¿ã€ããŒãå€éšãªãœãŒã¹ãžã®åŒã³åºããªã©ïŒãå®éã«ãã£ã³ã»ã«ãããå Žåã®æ·±ãã§ã
ãã£ã³ã»ã«ãããPromiseã®éèŠãªåŽé¢ã¯ããã£ã³ã»ã«æäœãå®å
šã«æåã§å®è£
ããå¿
èŠãããããšã§ãã ããšãã°ãç¬èªã®Promiseã¯ã©ã¹ãå®è£
ããããšã§ãèªåçã«éæããããšã¯ã§ããŸããã çè«çã«ã¯ãä»®æ³ãã·ã³ã§ã³ãŒããå®è¡ããããšã§åé¡ã解決ã§ããŸããä»®æ³ãã·ã³ã§ã¯ãPromiseåæåã¹ã¿ãã¯ã§éå§ããããã¹ãŠã®éåæã¢ã¯ã·ã§ã³ãšäŸåãããã©ã³ããèšé²ãããŸãããããã¯å®éã«ã¯ããªãéèŠãªã¿ã¹ã¯ã§ãããå®éã«ã¯ããŸã圹ã«ç«ã¡ãŸããã
ãããã£ãŠãEcmaScriptã§ãã£ã³ã»ã«ãããPromiseã¯ãè«çã¢ã¯ã·ã§ã³ã®ã«ãã»ã«åããããã§ãŒã³ã§ããPromiseãšãã§ã¯ããäžæããã³ãã£ã³ã»ã«ã§ããã€ã³ã¿ãŒãã§ã€ã¹èŠåã«ãããŸããã äžè¬çãªå Žåããã£ã³ã»ã«ã®æŠå¿µã¯ååšããŸããã
ç·šéè
ãã
ãããã¯ã«é¢ããNetologyã³ãŒã¹ïŒ