ì½ë°±, íë¼ë¯¸ì¤ ë±ì ì´ë»ê² ì¬ì©íëì§ ë³´ì¬ë리기 ìí´ ë³¸ ì±í°ìì ë¸ë¼ì°ì ì ì© ë©ìë를 ì¬ì©í ìì ì ëë¤. ì¤í¬ë¦½í¸ë¥¼ ë¶ë¬ì¤ê³ ìì±ë 문ìì ê°ë¨í ì¡°ìì íë ìììì í¹í ë¸ë¼ì°ì ë©ìëê° ì¬ì©ë ìì ì ëë¤.
ë¸ë¼ì°ì ë©ìëê° ìµìíì§ ìì ììê° ì ì´í´ëì§ ìëë¤ë©´ 문ì ê°ì²´ 모ë¸ì ì±í° ëª ê°ë¥¼ ì½ì´ë³´ì기 ë°ëëë¤.
ë ì를 ìí´ ìµëí ë¸ë¼ì°ì ë©ìë를 ë ì°ëë¡ íê² ìµëë¤.
ìë°ì¤í¬ë¦½í¸ í¸ì¤í¸ íê²½ì´ ì ê³µíë ì¬ë¬ í¨ì를 ì¬ì©íë©´ ë¹ë기(asynchronous) ëìì ì¤ì¼ì¤ë§ í ì ììµëë¤. ìíë ëì ëìì´ ììíëë¡ í ì ìì£ .
setTimeoutì ì¤ì¼ì¤ë§ì ì¬ì©ëë ê°ì¥ ëíì ì¸ í¨ìì
ëë¤.
ì¤ë¬´ìì ë§ë¥ë¨ë¦¬ë ë¹ë기 ëìì ì주 ë¤ìí©ëë¤. ì¤í¬ë¦½í¸ë 모ëì ë¡ë©íë ê² ëí ë¹ë기 ëìì ëë¤(ì´ ììë ë¤ìì 구체ì ì¼ë¡ ë¤ë£° ìì ì ëë¤).
srcì ìë ì¤í¬ë¦½í¸ë¥¼ ì½ì´ì¤ë í¨ì loadScript(src)를 ììë¡ ë¹ë기 ëì ì²ë¦¬ê° ì´ë»ê² ì¼ì´ëëì§ ì´í´ë´
ìë¤.
function loadScript(src) {
// <script> í그를 ë§ë¤ê³ íì´ì§ì í그를 ì¶ê°í©ëë¤.
// íê·¸ê° íì´ì§ì ì¶ê°ëë©´ srcì ìë ì¤í¬ë¦½í¸ë¥¼ ë¡ë©íê³ ì¤íí©ëë¤.
let script = document.createElement('script');
script.src = src;
document.head.append(script);
}
í¨ì loadScript(src)ë <script src="â¦">를 ëì ì¼ë¡ ë§ë¤ê³ ì´ë¥¼ 문ìì ì¶ê°í©ëë¤. ë¸ë¼ì°ì ë ìëì¼ë¡ íê·¸ì ìë ì¤í¬ë¦½í¸ë¥¼ ë¶ë¬ì¤ê³ , ë¡ë©ì´ ìë£ëë©´ ì¤í¬ë¦½í¸ë¥¼ ì¤íí©ëë¤.
loadScript(src) ì¬ì©ë²ì ë¤ìê³¼ ê°ìµëë¤.
// í´ë¹ ê²½ë¡ì ìì¹í ì¤í¬ë¦½í¸ë¥¼ ë¶ë¬ì¤ê³ ì¤íí¨
loadScript('/my/script.js');
ê·¸ë°ë° ì´ ë ì¤í¬ë¦½í¸ë âë¹ë기ì ì¼ë¡â ì¤íë©ëë¤. ë¡ë©ì ì§ê¸ ë¹ì¥ ììëëë¼ë ì¤íì í¨ìê° ëë íìì¼ ë기 ë문ì ëë¤.
ë°ë¼ì loadScript(â¦) ìëì ìë ì½ëë¤ì ì¤í¬ë¦½í¸ ë¡ë©ì´ ì¢
ë£ëë 걸 기ë¤ë¦¬ì§ ììµëë¤.
loadScript('/my/script.js');
// loadScript ìëì ì½ëë
// ì¤í¬ë¦½í¸ ë¡ë©ì´ ëë ëê¹ì§ 기ë¤ë¦¬ì§ ììµëë¤.
// ...
ì¤í¬ë¦½í¸ ë¡ë©ì´ ëëìë§ì ì´ ì¤í¬ë¦½í¸ë¥¼ ì¬ì©í´ 무ì¸ê°ë¥¼ í´ì¼ë§ íë¤ê³ ê°ì í´ ë´ ìë¤. ì¤í¬ë¦½í¸ ìì ë¤ìí í¨ìê° ì ìëì´ ìê³ , ì°ë¦¬ë ì´ í¨ì를 ì¤íí길 ìíë ìí©ì ëë¤.
ê·¸ë°ë° loadScript(...)를 í¸ì¶íìë§ì ë´ë¶ í¨ì를 í¸ì¶íë©´ ìíë ëë¡ ìëíì§ ììµëë¤.
loadScript('/my/script.js'); // script.jsì "function newFunction() {â¦}"ì´ ììµëë¤.
newFunction(); // í¨ìê° ì¡´ì¬íì§ ìëë¤ë ìë¬ê° ë°ìí©ëë¤!
ìë¬ë ë¸ë¼ì°ì ê° ì¤í¬ë¦½í¸ë¥¼ ì½ì´ì¬ ì ìë ìê°ì ì¶©ë¶í íë³´íì§ ëª»í기 ë문ì ë°ìí©ëë¤. ê·¸ë°ë° íì¬ë¡ìë í¨ì loadScriptìì ì¤í¬ë¦½í¸ ë¡ë©ì´ ìë£ëìëì§ ì ë°©ë²ì´ ìë¤ì. ì¸ì ê° ì¤í¬ë¦½í¸ê° ë¡ëëê³ ì¤íë ëê² ì§ë§, ê·¸ê² ë¤ì
ëë¤. ìíë ëë¡ ì¤í¬ë¦½í¸ ìì í¨ìë ë³ì를 ì¬ì©íë ¤ë©´ ì¤í¬ë¦½í¸ ë¡ë©ì´ ëë¬ëì§ ì¬ë¶ë¥¼ ì ì ìì´ì¼ í©ëë¤.
loadScriptì ë ë²ì§¸ ì¸ìë¡ ì¤í¬ë¦½í¸ ë¡ë©ì´ ëë í ì¤íë í¨ìì¸ ì½ë°±(callback) í¨ì를 ì¶ê°í´ ë´
ìë¤(ì½ë°± í¨ìë ëì¤ì í¸ì¶í í¨ì를 ì미í©ëë¤. â ì®ê¸´ì´).
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(script);
document.head.append(script);
}
ìë¡ê² ë¶ë¬ì¨ ì¤í¬ë¦½í¸ì ìë í¨ì를 ì½ë°± í¨ì ììì í¸ì¶íë©´ ìíë ëë¡ ì¸ë¶ ì¤í¬ë¦½í¸ ìì í¨ì를 ì¬ì©í ì ììµëë¤.
loadScript('/my/script.js', function() {
// ì½ë°± í¨ìë ì¤í¬ë¦½í¸ ë¡ëê° ëëë©´ ì¤íë©ëë¤.
newFunction(); // ì´ì í¨ì í¸ì¶ì´ ì ëë¡ ëìí©ëë¤.
...
});
ì´ë ê² ë ë²ì§¸ ì¸ìë¡ ì ë¬ë í¨ì(ëê° ìµëª í¨ì)ë ìíë ëì(ì ìì ìì ì¸ë¶ ì¤í¬ë¦½í¸ë¥¼ ë¶ë¬ì¤ë ê² â ì®ê¸´ì´)ì´ ìë£ëìì ë ì¤íë©ëë¤.
ìëë ì¤ì ì¡´ì¬íë ì¤í¬ë¦½í¸ë¥¼ ì´ì©í´ ë§ë ììì ëë¤. ì§ì ì¤íí´ ë´ ìë¤.
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(script);
document.head.append(script);
}
loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js', script => {
alert(`${script.src}ê° ë¡ëëììµëë¤.`);
alert( _ ); // ì¤í¬ë¦½í¸ì ì ìë í¨ì
});
ì´ë° ë°©ìì âì½ë°± 기ë°(callback-based)â ë¹ë기 íë¡ê·¸ëë°ì´ë¼ê³ í©ëë¤. 무ì¸ê°ë¥¼ ë¹ë기ì ì¼ë¡ ìííë í¨ìë í¨ì ë´ ëìì´ ëª¨ë ì²ë¦¬ë í ì¤íëì´ì¼ íë í¨ìê° ë¤ì´ê° ì½ë°±ì ì¸ìë¡ ë°ëì ì ê³µí´ì¼ í©ëë¤.
ì ìììì loadScriptì ì¸ìë¡ ì½ë°±ì ì ê³µí´ ì£¼ìëë°, ì´ë ê² ì½ë°±ì ì¬ì©í ë°©ìì ë¹ë기 íë¡ê·¸ëë°ì ì¼ë°ì ì¸ ì ê·¼ë²ì
ëë¤.
ì½ë°± ì ì½ë°±
ì¤í¬ë¦½í¸ê° ë ê° ìë ê²½ì°, ì´ë»ê² íë©´ ë ì¤í¬ë¦½í¸ë¥¼ ìì°¨ì ì¼ë¡ ë¶ë¬ì¬ ì ììê¹ì? ë ë²ì§¸ ì¤í¬ë¦½í¸ ë¡ë©ì 첫 ë²ì§¸ ì¤í¬ë¦½í¸ì ë¡ë©ì´ ëë ì´íê° ë길 ìíë¤ë©´ ë§ì´ì£ .
ê°ì¥ ìì°ì¤ë¬ì´ í´ê²° ë°©ë²ì ìëì ê°ì´ ì½ë°± í¨ì ììì ë ë²ì§¸ loadScript를 í¸ì¶íë ê²ì
ëë¤.
loadScript('/my/script.js', function(script) {
alert(`${script.src}ì ë¡ë©íìµëë¤. ì´ì , ë¤ì ì¤í¬ë¦½í¸ë¥¼ ë¡ë©í©ìë¤.`);
loadScript('/my/script2.js', function(script) {
alert(`ë ë²ì§¸ ì¤í¬ë¦½í¸ë¥¼ ì±ê³µì ì¼ë¡ ë¡ë©íìµëë¤.`);
});
});
ì´ë ê² ì¤ì²© ì½ë°±ì ë§ë¤ë©´ ë°ê¹¥ì ìì¹í loadScriptê° ìë£ë í, ì쪽 loadScriptê° ì¤íë©ëë¤.
ê·¸ë°ë° ì¬ê¸°ì ëíì¬ ì¤í¬ë¦½í¸ë¥¼ íë ë ë¶ë¬ì¤ê³ ì¶ë¤ë©´ ì´ë»ê² í´ì¼ í ê¹ì?
loadScript('/my/script.js', function(script) {
loadScript('/my/script2.js', function(script) {
loadScript('/my/script3.js', function(script) {
// ì¸ ì¤í¬ë¦½í¸ ë¡ë©ì´ ëë í ì¤íë¨
});
})
});
ìì ê°ì´ 모ë ìë¡ì´ ëìì´ ì½ë°± ìì ìì¹íê² ìì±íë©´ ë©ëë¤. ê·¸ë°ë° ì´ë ê² ì½ë°± ìì ì½ë°±ì ë£ë ê²ì ìííë ¤ë ëìì´ ë¨ ëª ê°ë¿ì´ë¼ë©´ ê´ì°®ì§ë§, ëìì´ ë§ì ê²½ì°ì ì¢ì§ ììµëë¤. ë¤ë¥¸ ë°©ìì¼ë¡ ì½ë를 ìì±íë ë°©ë²ì ê³§ ììë³´ëë¡ íê² ìµëë¤.
ìë¬ í¸ë¤ë§
ì§ê¸ê¹ì§ ì´í´ë³¸ ììë¤ì ì¤í¬ë¦½í¸ ë¡ë©ì´ ì¤í¨íë ê²½ì° ë±ì ìë¬ë¥¼ ê³ ë ¤íì§ ìê³ ìì±ëììµëë¤. ê·¸ë°ë° ì¤í¬ë¦½í¸ ë¡ë©ì´ ì¤í¨í ê°ë¥ì±ì ì¸ì ë ììµëë¤. ë¬¼ë¡ ì½ë°± í¨ìë ì´ë° ìë¬ë¥¼ í¸ë¤ë§í ì ìì´ì¼ íì£ .
loadScriptìì ë¡ë© ìë¬ë¥¼ ì¶ì í ì ìê² ê¸°ë¥ì ê°ì í´ë´
ìë¤.
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(null, script);
script.onerror = () => callback(new Error(`${src}를 ë¶ë¬ì¤ë ëì¤ì ìë¬ê° ë°ìíìµëë¤.`));
document.head.append(script);
}
ì´ì loadScriptë ì¤í¬ë¦½í¸ ë¡ë©ì ì±ê³µíë©´ callback(null, script)ì, ì¤í¨íë©´ callback(error)ì í¸ì¶í©ëë¤.
ê°ì ë loadScriptì ì¬ì©ë²ì ë¤ìê³¼ ê°ìµëë¤.
loadScript('/my/script.js', function(error, script) {
if (error) {
// ìë¬ ì²ë¦¬
} else {
// ì¤í¬ë¦½í¸ ë¡ë©ì´ ì±ê³µì ì¼ë¡ ëë¨
}
});
ì´ë ê² ìë¬ë¥¼ ì²ë¦¬íë ë°©ìì íí ì¬ì©ëë í¨í´ì ëë¤. ì´ë° í¨í´ì 'ì¤ë¥ ì°ì ì½ë°±(error-first callback)'ì´ë¼ê³ ë¶ë¦½ëë¤.
ì¤ë¥ ì°ì ì½ë°±ì ë¤ì ê´ë¡ë¥¼ ë°ë¦ ëë¤.
callbackì 첫 ë²ì§¸ ì¸ìë ìë¬ë¥¼ ìí´ ë¨ê²¨ë¡ëë¤. ìë¬ê° ë°ìíë©´ ì´ ì¸ì를 ì´ì©í´callback(err)ì´ í¸ì¶ë©ëë¤.- ë ë²ì§¸ ì¸ì(íìíë©´ ì¸ì를 ë ì¶ê°í ì ìì)ë ìë¬ê° ë°ìíì§ ììì ë를 ìí´ ë¨ê²¨ë¡ëë¤. ìíë ëìì´ ì±ê³µí ê²½ì°ì
callback(null, result1, result2...)ì´ í¸ì¶ë©ëë¤.
ì¤ë¥ ì°ì ì½ë°± ì¤íì¼ì ì¬ì©íë©´, ë¨ì¼ ì½ë°± í¨ììì ìë¬ ì¼ì´ì¤ì ì±ê³µ ì¼ì´ì¤ 모ë를 ì²ë¦¬í ì ììµëë¤.
멸ë§ì í¼ë¼ë¯¸ë
ì½ë°± ê¸°ë° ë¹ë기 ì²ë¦¬ë ì¸ë» ë´¤ì ë 꽤 ì¸ë§í´ ë³´ì´ê³ , ì¤ì ë¡ë ê·¸ë ìµëë¤. í ê° í¹ì ë ê°ì ì¤ì²© í¸ì¶ì´ ìë ê²½ì°ë 보기ìë ëìì§ ììµëë¤.
íì§ë§ 꼬리ì 꼬리를 무ë ë¹ë기 ëìì´ ë§ìì§ë©´ ìëì ê°ì ì½ë ìì±ì´ ë¶ê°í¼í´ì§ëë¤.
loadScript('1.js', function(error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript('2.js', function(error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript('3.js', function(error, script) {
if (error) {
handleError(error);
} else {
// 모ë ì¤í¬ë¦½í¸ê° ë¡ë©ë í, ì¤í íë¦ì´ ì´ì´ì§ëë¤. (*)
}
});
}
})
}
});
ì ì½ëë ë¤ìê³¼ ê°ì´ ëìí©ëë¤.
1.js를 ë¡ëí©ëë¤. ê·¸ í ìë¬ê° ìì¼ë©´,2.js를 ë¡ëí©ëë¤. ê·¸ í ìë¬ê° ìì¼ë©´,3.js를 ë¡ëí©ëë¤. ê·¸ í ìë¬ê° ìì¼ë©´(*)ë¡ íìí ì¤ìì ë ë¤ë¥¸ ìì ì ìíí©ëë¤.
í¸ì¶ì´ ê³ì ì¤ì²©ëë©´ì ì½ëê° ê¹ì´ì§ê³ ìë¤ì. 본문 ì¤ê°ì¤ê° ...ë¡ íìí ê³³ì ë°ë³µë¬¸ê³¼ ì¡°ê±´ë¬¸ì´ ìë ì½ëê° ë¤ì´ê°ë©´ ê´ë¦¬ë í¹íë ë íë¤ì´ì§ ê²ëë¤.
ì´ë ê² ê¹ì ì¤ì²© ì½ëê° ë§ë¤ì´ë´ë í¨í´ì ìì âì½ë°± ì§ì¥(callback hell)â í¹ì '멸ë§ì í¼ë¼ë¯¸ë(pyramid of doom)'ë¼ê³ ë¶ë¦½ëë¤.
ë¹ë기 ëìì´ íëì© ì¶ê°ë ëë§ë¤ ì¤ì²© í¸ì¶ì´ ë§ë¤ì´ë´ë 'í¼ë¼ë¯¸ëâë ì¤ë¥¸ìª½ì¼ë¡ ì ì 커ì§ëë¤. ê³§ ìì¸ ì ìë ì§ê²½ì´ ëì´ë²ë¦¬ì£ .
ë°ë¼ì ì´ë° ì½ë© ë°©ìì ì¢ì§ ììµëë¤.
ê° ëìì ë 립ì ì¸ í¨ìë¡ ë§ë¤ì´ ìì ê°ì 문ì 를 ìíí´ ë³´ëë¡ í©ìë¤. ìëì ê°ì´ ë§ì´ì£ .
loadScript('1.js', step1);
function step1(error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript('2.js', step2);
}
}
function step2(error, script) {
if (error) {
handleError(error);
} else {
// ...
loadScript('3.js', step3);
}
}
function step3(error, script) {
if (error) {
handleError(error);
} else {
// 모ë ì¤í¬ë¦½í¸ê° ë¡ë©ëë©´ ë¤ë¥¸ ëìì ìíí©ëë¤. (*)
}
};
ì´ë¤ê°ì? ìë¡ê² ìì±í ì½ëë ê° ëìì ë¶ë¦¬í´ ìµìì ë 벨ì í¨ìë¡ ë§ë¤ì기 ë문ì ê¹ì ì¤ì²©ì´ ììµëë¤. ê·¸ë¦¬ê³ ì½ë°± ê¸°ë° ì¤íì¼ ì½ëì ëì¼íê² ëìíì£ .
ê·¸ë°ë° ì´ë ê² ìì±íë©´ ëììì 문ì ë ìì§ë§, ì½ëê° ì°¢ì´ì§ ì¢ ìì¡°ê° ê°ì ë³´ì¸ë¤ë 문ì ê° ìê¹ëë¤. ì½ë ê²ë ì´ë ¤ìì§ì£ . ëì ì´ë¦¬ì 리 ìì§ì´ë©° ì½ë를 ì½ì´ì¼ í©ëë¤. ì½ëì ìµìì§ ìì ëì ì´ëë¡ ì®ê²¨ì¼ í ì§ ëª¨ë¥´ë©´ ëì±ë ë¶í¸í ê²ì ëë¤.
ê²ë¤ê° step*ì´ë¼ê³ ëª
ëª
í í¨ìë¤ì '멸ë§ì í¼ë¼ë¯¸ëâ를 í¼íë ¤ë ì©ëë§ì¼ë¡ ë§ë¤ì기 ë문ì ì¬ì¬ì©ì´ ë¶ê°ë¥í©ëë¤. ê·¸ ë구ë ì°ì ëìì´ ì´ë¤ì§ë ì½ë ë°ìì í¨ìë¤ì ì¬íì©íì§ ìì ê²ëë¤. ë¤ìì¤íì´ì¤ê° ì½ê° ë³µì¡í´ì¡ë¤ì(namespace cluttering).
ì§ê¸ì¯¤ì´ë©´ ë ëì 무ì¸ê°ê° íìíë¤ë ìê°ì´ ê°íê² ë¤ ê²ëë¤.
ì´ ì¢ê²ë, 멸ë§ì í¼ë¼ë¯¸ë를 í¼í ë°©ë²ì´ ëª ê°ì§ ììµëë¤. ê°ì¥ ì¢ì ë°©ë² ì¤ íëë ë¤ì ì±í°ìì ì¤ëª í 'íë¼ë¯¸ì¤(promise)'를 ì¬ì©íë ê²ì ëë¤.
ëê¸
<code>í그를, ì¬ë¬ ì¤ë¡ 구ì±ë ì½ë를 ì½ì íê³ ì¶ë¤ë©´<pre>í그를 ì´ì©íì¸ì. 10ì¤ ì´ìì ì½ëë plnkr, JSBin, codepen ë±ì ìëë°ì¤ë¥¼ ì¬ì©íì¸ì.