โ ์ฝ๋ฐฑ ํจ์
์ฝ๋ฐฑ์ด๋?
๋์ค์ ์คํ๋๋ ์ฝ๋
์์
1) A()๋ผ๋ ํจ์์ ์ธ์๋ก ์ด๋ค ํจ์๋ฅผ ๋ฃ์ด์ค.
(์๋ฐ์คํฌ๋ฆฝํธ์์ ํจ์๋ '์ผ๊ธ ๊ฐ์ฒด'์ด๋ฏ๋ก ์ธ์๋ก ํจ์๋ฅผ ๋ฃ์ด์ฃผ๋ ๊ฒ์ด ๊ฐ๋ฅํจ)
2) A ํจ์์ ๋ชจ๋ ๋ช ๋ น์ ์คํํ ํ ๋ง์ง๋ง์ผ๋ก ๋๊ฒจ ๋ฐ์ ์ธ์ callback์ ์คํํจ.
โก ์ด ๋ฉ์ปค๋์ฆ์ด '์ฝ๋ฐฑ'์ด๊ณ , ์ฌ๊ธฐ์ ์ธ์๋ก ๋ค์ด๊ฐ๋ ํจ์๊ฐ '์ฝ๋ฐฑ ํจ์'
๐ก ์ฉ์ด ์ ๋ฆฌ ๐ก
์ผ๊ธ ๊ฐ์ฒด : ๋ค๋ฅธ ๊ฐ์ฒด์ ์ผ๋ฐ์ ์ผ๋ก ์ ์ฉํ ์ ์๋ ์ฐ์ฐ์ ๋ชจ๋ ์ง์ํ๋ ๊ฐ์ฒด
์ผ๊ธ ๊ฐ์ฒด๋ ๋ค๋ฅธ ํจ์์ ์ธ์(ํ๋ผ๋ฏธํฐ)๋ก ๋ฃ์ ์ ์๊ณ , ๋ฐํ ๊ฐ์ผ๋ก๋ ์ฐ์ด๋ฉฐ, ๋ณ์ ์์ ๋ฃ์ ์๋ ์์.
1. ๋น๋๊ธฐ ์ฒ๋ฆฌ
setTimeout(callback, delayTime)
: ์ฝ๋ฐฑ ํจ์์ ์ง์ฒดํ ์๊ฐ์ ์ธ์๋ก ๋ฐ์, ์ธ์๋ก ๋ฐ์ ์๊ฐ๋งํผ ๊ธฐ๋ค๋ ธ๋ค๊ฐ ์ฝ๋ฐฑ ํจ์๋ฅผ ์คํํ๋ ํจ์ (JS ๋ด์ฅํจ์)
1) ์ฝ๋ฐฑ ํจ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ
/* sample 17 */
// 1๋ฒ ํจ์
setTimeout(()=>{
console.log('todo: First Work!');
}, 3000);
// 2๋ฒ ํจ์
setTimeout(()=>{
console.log('todo: Second Work!');
}, 2000);
// ์ถ๋ ฅ๊ฒฐ๊ณผ
/*
todo: Second Work!
todo: First Work!
*/
- First work! ๋ก๊ทธ๋ฅผ ์ฐ๋ 1๋ฒ ํจ์๋ฅผ ๋จผ์ ํธ์ถํจ
- ๊ทธ๋ฌ๋ 1๋ฒ ํจ์๋ ์ง์ฒดํ ์๊ฐ์ด 3000ms์ด๊ณ 2๋ฒ ํจ์๋ 2000ms ์ด๊ธฐ ๋๋ฌธ์
1๋ฒ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ 2๋ฒ ๋จผ์ ์ถ๋ ฅํจ.
์๋ฐ์คํฌ๋ฆฝํธ๋ ์ด๋ฒคํธ ์ค์ฌ ์ธ์ด์ด๊ธฐ ๋๋ฌธ์
์ด๋ค ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ๊ทธ์ ๋ํ ๊ฒฐ๊ณผ๊ฐ ์ฌ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ,
๋ค์ ์ด๋ฒคํธ๋ฅผ ๊ณ์ํด์ ์คํํจ.
2) ์ฝ๋ฐฑ ํจ์์ ๋๊ธฐ ์ฒ๋ฆฌ
/* sample 18 */
// 1๋ฒ ํจ์
setTimeout(()=>{
setTimeout(()=>{ // 2๋ฒ ํจ์
console.log('todo: Second Work!');
}, 2000);
console.log('todo: First work!');
}, 3000);
// ์ถ๋ ฅ๊ฒฐ๊ณผ
/*
todo: First work!
todo: Second Work!
*/
- ์ฝ๋ฐฑํจ์๋ก 2๋ฒ setTimeout()์ ๋ณด๋
- 3000ms ์๋ค๊ฐ 2๋ฒ ํจ์๋ฅผ ๋ณด๋ด๊ณ , 'First work' ์ถ๋ ฅ
- 2000ms ์๋ค๊ฐ 2๋ฒ ํจ์์ 'Second work' ์ถ๋ ฅ
โก ์์ฐจ์ ์ผ๋ก ์คํํ๊ณ ์ถ๋ค๋ฉด, '์ฝ๋ฐฑ ํจ์'๋ฅผ ์ด์ฉํ์ฌ ๋น๋๊ธฐ ์์ ์ ๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํด์ค์ผํจ.
2. API vs ์ฌ์ฉ์ ์ ์ ํจ์
1) ์ฌ์ฉ์ ์ ์ ํจ์์ ๋๊ธฐ ์ฒ๋ฆฌ
/* sample 19 */
function fakeSetTimeout(callback){
callback();
}
// 1๋ฒ
console.log(0);
// 2๋ฒ
fakeSetTimeout(function(){
console.log('Hello');
});
// 3๋ฒ
console.log(1);
// ์ถ๋ ฅ ๊ฒฐ๊ณผ
/*
0
Hello
1
*/
- 1๋ฒ ์ฝ์คํ์์ ์คํ
- 2๋ฒ ์ฝ์คํ์์ ์คํ
-3๋ฒ ์ฝ์คํ์์ ์คํ
โก ์ฝ๋ฐฑ ํ๋ฅผ ๊ฑฐ์น์ง ์๊ณ ๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌ๋จ.
2) API์ ๋น๋๊ธฐ์ ์ฒ๋ฆฌ
/* sample 20 */
// 1๋ฒ
console.log(0);
// 2๋ฒ
setTimeout(function(){
console.log('Hello');
}, 0);
// 3๋ฒ
console.log(1);
// ์ถ๋ ฅ ๊ฒฐ๊ณผ
/*
0
1
Hello
*/
- 1๋ฒ ์ฝ์คํ์์ ์คํ
- 2๋ฒ์ ์ฝ๋ฐฑ ํจ์์ด๋ฏ๋ก ์ฝ๋ฐฑ ํ๋ก ๋ค์ด๊ฐ.
- 3๋ฒ ์ฝ์คํ์์ ์คํ
- ์ฝ์คํ์ด ๋น์์ผ๋ฏ๋ก ์ฝ๋ฐฑ ํ์ ๋ค์ด๊ฐ 2๋ฒ ์คํ
3) ๋๊ธฐ์ ๋น๋๊ธฐ
- ๋๊ธฐ์ ์์
์ ๋ชจ๋ '์ฝ ์คํ'์ผ๋ก ๋ค์ด๊ฐ ์ฒ๋ฆฌ๋จ.
- ๋น๋๊ธฐ์ ์์
์ ๋ชจ๋ '์ฝ๋ฐฑ ํ'์ ๋ฃ๊ณ , '์ฝ ์คํ'์ด ๋น์ด์ผ ์คํํ ์ ์์.
๋ด๋ถ์์ ์ฒ๋ฆฌ๋๋ ์ฐ์ฐ - ๋๊ธฐ์ ์ฒ๋ฆฌ
์ธ๋ถ์์ ์ฒ๋ฆฌ๋๋ ์ฐ์ฐ(์๋ฒ์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ, ํ์ด๋จธ ๋ฑ์ ์ธ๋ถ API) - ๋น๋๊ธฐ์ ์ฒ๋ฆฌ
โก ์๋ฐ์คํฌ๋ฆฝํธ๋ ๋ฐ์ ์น ํ๊ฒฝ์์ ์ฌ๋ฌ ์์ ์ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋น๋๊ธฐ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํจ!
โก '์ฝ๋ฐฑ ์ง์ฅ'์ ๋น ์ง์ง ์๋๋ก ์ฃผ์ํด์ผ ํจ.
โ Promise
Promise๋?
๋ณด๋ธ ์์ฒญ์ ๋ํด ์๋ต์ด ์ค๋น๋์์ ๋ ์๋ฆผ์ ์ฃผ๋ ์ญํ !
1. ์ผ๋ฐ์ ์ธ ๋น๋๊ธฐ์ ๋๊ธฐ์ ์ฒ๋ฆฌ
1) ์ผ๋ฐ ๋น๋๊ธฐ ํจ์
/* sample 21-1 */
function work(sec, callback){
setTimeout(()=>{
callback(new Date().toISOString());
}, sec * 1000);
};
work(1, (result)=>{
console.log('์ฒซ ๋ฒ์งธ ์์
', result);
});
work(1, (result) =>{
console.log('๋ ๋ฒ์งธ ์์
', result);
});
work(1, (result) =>{
console.log('์ธ ๋ฒ์งธ ์์
', result);
});
// ์ถ๋ ฅ ๊ฒฐ๊ณผ
/*
์ฒซ ๋ฒ์งธ ์์
2022-08-18T06:06:25.739Z
๋ ๋ฒ์งธ ์์
2022-08-18T06:06:25.748Z
์ธ ๋ฒ์งธ ์์
2022-08-18T06:06:25.748Z
*/
์ฐจ๋ก๋ก ์ถ๋ ฅ์ด ๋๊ธด ํ์ง๋ง, ๋ชจ๋ ๊ฐ์ ์๊ฐ์ ์์ ์ด ๋๋จ.
2) ๋๊ธฐ์ ์ฒ๋ฆฌ - 1
/* sample 21-2 */
function work(sec, callback){
setTimeout(()=>{
callback(new Date().toISOString());
}, sec * 1000);
};
work(1, (result)=>{
console.log('์ฒซ ๋ฒ์งธ ์์
', result);
work(1, (result) =>{
console.log('๋ ๋ฒ์งธ ์์
', result);
work(1, (result) =>{
console.log('์ธ ๋ฒ์งธ ์์
', result);
});
});
});
// ์ถ๋ ฅ ๊ฒฐ๊ณผ
/*
์ฒซ ๋ฒ์งธ ์์
2022-08-18T06:14:47.375Z
๋ ๋ฒ์งธ ์์
2022-08-18T06:14:48.396Z
์ธ ๋ฒ์งธ ์์
2022-08-18T06:14:49.400Z
*/
- ์ฒซ ๋ฒ์งธ ์์ ์ด ๋๋จ.
- 1์ด ๋ค์ ๋ ๋ฒ์งธ ์์ ์ด ๋๋จ.
- 1์ด ๋ค์ ์ธ ๋ฒ์งธ ์์ ์ด ๋๋จ.
3) ๋๊ธฐ์ ์ฒ๋ฆฌ - 2
/* sample 21-3 */
function work(sec, callback){
setTimeout(()=>{
callback(new Date().toISOString());
}, sec * 1000);
};
work(1, (result)=>{
console.log('์ฒซ ๋ฒ์งธ ์์
', result);
work(1, (result) =>{
work(1, (result) =>{
console.log('์ธ ๋ฒ์งธ ์์
', result);
});
console.log('๋ ๋ฒ์งธ ์์
', result);
});
});
// ์ถ๋ ฅ ๊ฒฐ๊ณผ
/*
์ฒซ ๋ฒ์งธ ์์
2022-08-18T06:16:53.301Z
๋ ๋ฒ์งธ ์์
2022-08-18T06:16:54.322Z
์ธ ๋ฒ์งธ ์์
2022-08-18T06:16:55.326Z
*/
- ๋น๋๊ธฐ์ ์ผ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ณผ๋ ์์ ์์ ์ ๋๊ฐ์.
๋จ์ : ๋๊ธฐ์ ์ฒ๋ฆฌ๋ก ๋ฐ๊พธ๋ฉด์ ํ ๋์ ํ์ ํ๊ธฐ๊ฐ ํ๋ค์ด์ง.
โก ์ด๊ฒ์ ๊ทน๋ณตํ๊ธฐ ์ํด Promise ์ฌ์ฉ!
2. Promise๋ฅผ ์ฌ์ฉํ ๋๊ธฐ์ ์ฒ๋ฆฌ
- '์ฝ๋ฐฑ ์ง์ฅ'์ ํ์ถํ๊ฒ ํด์ฃผ๋ ์๋ฐ์คํฌ๋ฆฝํธ API
1) Promise์ ์ธ์คํด์ค๋ฅผ ๋ฐํ
2) then์์ ๋ฐํํ ๊ฒ์ ๋ฐ์
/* sample 22 */
function workP(sec){
return new Promise((resolve, reject) => {
// Promise ์์ฑ์ ๋๊ธฐ๋ callback = resolve, reject
// resolve ๋์ ์๋ฃ์ ํธ์ถ, ์ค๋ฅ ๋ฌ์ ๊ฒฝ์ฐ reject
setTimeout(() => {
resolve(new Date().toISOString());
}, sec * 1000);
});
}
workP(1).then((result)=>{
console.log('์ฒซ๋ฒ์งธ ์์
', result);
return workP(1);
}).then((result)=>{
console.log('๋๋ฒ์งธ ์์
', result);
});
// ์ถ๋ ฅ๊ฒฐ๊ณผ
/*
์ฒซ๋ฒ์งธ ์์
2022-08-18T06:21:16.005Z
๋๋ฒ์งธ ์์
2022-08-18T06:21:17.021Z
*/
1) workP() ๋ผ๋ ํจ์๋ new ํค์๋๋ฅผ ํตํด Promise์ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ๋ฐํ
2) Promise๋ฅผ ์์ฑํ ๋ resolve์ reject๋ฅผ ๋๊น
3) workP()๋ฅผ ํธ์ถํ๊ณ ๋ฐํ๋๋ Promise์ ์ธ์คํด์ค๋ฅผ ๋ฐ์ resolve๋ฅผ ํตํด ๋ฐ์ ๊ฒฐ๊ณผ ๊ฐ์ ์ฌ์ฉํจ.
4) then()์ Chainingd์ ํ์ฌ ์ฌ์ฉํจ
- ์ฒซ ๋ฒ์งธ then()์์, ๋ ๋ฒ์งธ then()์ด ๋ฐ๊ณ ์ถ์ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐํ
- ๋ ๋ฒ์งธ then()์์, ์ธ ๋ฒ์งธ then()์ด ๋ฐ๊ณ ์ถ์ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐํ
...
โก ๋ฐ๋์ then()์ด ๋๋๊ณ ๋ฌด์ธ๊ฐ๋ฅผ ๋ฐํํด์ฃผ์ด์ผ ๋ค์ then()์์ ์ด๋ฅผ ๋ฐ์ ๋ฌด์ธ๊ฐ๋ฅผ ์คํํ ์ ์์.
1. ์ธ์คํด์ค - ์ฝ๋์ ๊ตฌํ๋ ๊ฐ์ฒด๊ฐ ์ค์ ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น๋ ๊ฒ
2. resolve - ์ฑ๊ณตํ ๊ฒฝ์ฐ ํธ์ถ (callback ํจ์์ ๋น์ทํจ)
3. reject - ์คํจํ ๊ฒฝ์ฐ ํธ์ถ
โ async / await
1. async / await์ด๋?
Promise์ ๋จ์ ์ ๋ณด์ํด์ฃผ๋ ํจํด
(๋น๋๊ธฐ ์ฝ๋์ ๊ฒ๋ชจ์ต๊ณผ ๋์์ ์ข ๋ ๋๊ธฐ์ฝ๋์ ์ ์ฌํ๊ฒ ๋ง๋ค์ด์ค)
1) Promise๋ฅผ ์ฌ์ฉํ ์ฝ๋
const makeRequest = () =>{
getJSON()
.then(data => {
console.log(data);
return 'done';
});
}
makeRequest();
2) async / await์ ์ฌ์ฉํ ์ฝ๋
// ex - awync/await
const makeRequest = async() => {
console.log(await getJSON());
return 'done';
}
makeRequest();
2. async / await์ ์ฅ์
1) new Promise๋ก Promise ๊ฐ์ฒด๋ฅผ ์ ์ธํ๊ณ resolve, reject๋ฅผ ๋๊ฒจ์ฃผ๋ ๋ถ๋ถ์ ์จ๊น
2) try / catch๋ฅผ ํตํ ์ค๋ฅ๋ฅผ ๋ค๋ฃฐ ์ ์์
3) ์ค์ฒฉ ํ์ ํด๊ฒฐ ๊ฐ๋ฅ
/* sample 23 */
function workP(sec){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(new Date().toISOString());
}, sec * 1000);
});
}
function justFunc(){
return 'just Function';
}
async function asyncFunc(){
return 'async Function';
}
console.log(
justFunc(),
asyncFunc(),
workP()
);
// ์ถ๋ ฅ๊ฒฐ๊ณผ
// just Function Promise { 'async Function' } Promise { <pending> }
3. async / await์ ์ฌ์ฉ๋ฒ
1) async๋ Promise ๊ฐ์ฒด๋ฅผ ๋ฐํํจ.
โก Promise๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ Promise ํจํด์์์ฒ๋ผ ํจ์๋ฅผ ํธ์ถํ ๋ then()์ ์ฌ์ฉํ ์ ์์.
2) await์ ์ฌ์ฉ๋ฒ
: async ํค์๋๋ฅผ ๋ถ์ธ ํจ์ ์์ lock์ ๊ฑธ์ด ๋๊ณ ์ถ์ ๋ถ๋ถ์ await๋ฅผ ๋ถ์ด๋ฉด ๋จ.
/* sample 24 */
function workP(sec){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('workP function');
}, sec * 1000);
});
}
async function asyncFunc(){
const result_workP = await workP(3);
console.log(result_workP);
return 'async function';
}
asyncFunc().then((result)=>{
console.log(result);
});
// ์ถ๋ ฅ ๊ฒฐ๊ณผ
/*
workP function
async function
*/
workP() ํจ์๋ฅผ ํธ์ถํ๋ ๋ถ๋ถ์ await์ ๋ถ์
โก ์๋ workP ํจ์๋ setTimeout() ํจ์๋ฅผ ์ด์ฉํ๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌ๋จ.
โก ๊ทธ๋ฌ๋ await๋ฅผ ๋ถ์๊ธฐ ๋๋ฌธ์ workP(3) ํจ์๊ฐ ์๋ฃ๋๊ธฐ ์ ๊น์ง ๊ทธ ๋ฐ์ ๊ตฌ๋ฌธ์ ์คํํ์ง ์์.