๋ณธ ํฌ์คํ ์ ์ ๋ก์ด๋์ ์ ํ๋ธ ๊ฐ์ข '์ธ๊ฐ JS ์์ง ๋๊ธฐ'๋ฅผ ํตํด ํ์ตํ๋ฉฐ ์์ฑํ์์ต๋๋ค.
2-0. Promise, async/await
ํ๋ก๋ฏธ์ค๋, ๋ด์ฉ์ด ์คํ์ ๋์์ง๋ง ๊ฒฐ๊ณผ๋ฅผ ์์ง ๋ฐํํ์ง ์์ ๊ฐ์ฒด๋ค.
const condition = true;
const promise = new Promise((resolve, reject) => {
if (condition) {
resolve('์ฑ๊ณต');
} else {
reject('์คํจ');
}
});
// ๋ค๋ฅธ ์ฝ๋๊ฐ ๋ค์ด๊ฐ ์ ์์
promise
.then((message) => {
console.log(message); // ์ฑ๊ณต(resolve)ํ ๊ฒฝ์ฐ ์คํ
})
.catch(error) => {
console.error(error); // ์คํจ(reject)ํ ๊ฒฝ์ฐ ์คํ
}
resolve(์ฑ๊ณต ๋ฆฌํด ๊ฐ)๋ then์ผ๋ก ์ฐ๊ฒฐ๋๊ณ , reject(์คํจ ๋ฆฌํด ๊ฐ)๋ catch๋ก ์ฐ๊ฒฐ๋๋ค. finally ๋ถ๋ถ์ ๋ฌด์กฐ๊ฑด ์คํ๋๋ค.
const promise1 = Promise.resolve('์ฑ๊ณต1');
const promise2 = Promise.resolve('์ฑ๊ณต2'):
Promise.all([promise1, promise2]) // ์ฌ๋ฌ๊ฐ์ ํ๋ก๋ฏธ์ค๋ฅผ ๋์์ ์คํ
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error(err);
});
Promise.all(๋ฐฐ์ด)
์ ์ฌ๋ฌ ๊ฐ์ ํ๋ก๋ฏธ์ค๋ฅผ ๋์์ ์คํํ ์ ์๋๋ฐ, ํ๋๋ผ๋ ์คํจํ๋ฉด catch๋ก ๊ฐ๋ค. Promise.allSettled
๋ก ์คํจํ ๊ฒ๋ง ์ถ๋ ค๋ผ ์ ์๋ค.
- ์ฝ๋ฐฑ ํจํด(3์ค์ฒฉ)
function findAndSaveUser(Users) {
Users.findOne({}, (err, user) => {
if (err) {
return console.error(err);
}
user.name = 'zero';
user.save((err) => {
if (err) {
return console.error(err);
}
Users.findOne({gender: 'm'}, (err, user) => {
// ์๋ต
});
}
}
}
- findOne, save ๋ฉ์๋๊ฐ ํ๋ก๋ฏธ์ค๋ฅผ ์ง์ํ๋ค๊ณ ๊ฐ์ ํ์ฌ promise๋ฅผ ์ฌ์ฉํ๋๋ก ์ฝ๋ ์์
function findAndSaveUser(Users) {
Users.findOne({})
.then((user) => {
user.name = 'zero';
return user.save();
})
.then((user) => {
return Users.findOne({ gender: 'm'});
})
.then((user) => {
// ์๋ต
})
.catch(err => {
console.error(err)
});
}
- async/await์ผ๋ก ์ถ์ฝ
async function findAndSaveUser(Users) {
let user = await Users.findOne({}); // ์คํ ์์๊ฐ ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ
user.name = 'zero';
user = await user.save();
user = await Users.findOne({gender: 'm'});
// ์๋ต
}
- ํ์ดํ ํจ์๋ async/await ๊ฐ๋ฅ
const findAndSaveUser = async (Users) => {
try {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({gender: 'm'}});
//์๋ต
} catch (error) {
console.error(err);
}
};
- aysnc ํจ์๋ ํญ์ promise๋ฅผ ๋ฐํ -> then์ด๋ await์ ๋ถ์ผ ์ ์๋ค.
async function findAndSaveUser(Users) {
// ์๋ต
}
findAndSaveUser().then(()=>{/* ์๋ต */});
// ๋๋
async function other() {
const result = await findAndSaveUser();
}
- for await์ ํตํด ๋ฐ๋ณต๋ฌธ์ ๋๋ฆด ์ ์๋ค.
const promise1 = Promise.resolve('์ฑ๊ณต1');
const promise2 = Promise.resolve('์ฑ๊ณต2');
(async () => {
for await (promise of [promise1, promise2]) {
console.log(promise);
}
})();
2-1. ํ๋ก๋ฏธ์ค์ ์ต๊ณ ์ฅ์ ์ ์์ญ๋๊น
setTimeout(() => {
console.log('a');
}, 1000);
์ ์ฝ๋๋ 1์ด ๋ค๋ผ๋ ์กฐ๊ฑด์ด ๋ฌ์ฑ๋๋ฉด console.log('a')
๊ฐ ๋ฐ๋ก ์คํ๋์ด๋ฒ๋ฆฌ๋ ๋จ์ ์ด ์๋ค.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 1000);
});
๋ฐ๋ฉด ์ ์ฝ๋์์๋ setTimeout์ด ์คํ๋์ง๋ง, ๊ทธ ๊ฒฐ๊ณผ๊ฐ์ ๋์ค์ ์ฌ์ฉํ ์ ์๋ค. ๊ณ์ ๋ค๋ฅธ ํ๋์ ํ๋ค๊ฐ promise.them(() => { console.log('a') }
์ ์คํํด๋ ์๋ฌด๋ฐ ๋ฌธ์ ๊ฐ ์๋ค๋ ๋ป์ด๋ค. ์ฆ ์คํ ๋ถ๋ถ์ ๋ถ๋ฆฌํด์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ก ๋ฐ๊ณ ์ถ์ง ์์ผ๋ฉด ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ด์๋๊ณ ์๋ค๊ฐ ์ฌ์ฉํ ์ ์๋ค.
axios.get('์๋ฒ์ฃผ์1', function(๋ฐ์ดํฐ1){
axios.get('์๋ฒ์ฃผ์2', function(๋ฐ์ดํฐ2) {
axios.get('์๋ฒ์ฃผ์3', function(๋ฐ์ดํฐ3) {
...
});
}
});
const p1 = axios.get('์๋ฒ์ฃผ์1');
const p2 = axios.get('์๋ฒ์ฃผ์2');
const p3 = axios.get('์๋ฒ์ฃผ์3');
Promise.all([p1, p2, p3]).then((results) => {}).catch((error) => {}).finally(()=>{});
// ์ ์ฝ๋์์ catch๋ Promise.all์ ๋ํ catch๊ฐ ์๋๋ผ, Promise.all().then()์ ๋ํ catch์ด๋ฏ๋ก then์์ ์ค๋ฅ๊ฐ ๋ฐ์ํด๋ catch๋ก ๊ฐ๋ค.
Promise.allSettled([p1, p2, p3]).then((results) => {
// ์คํจํ ๊ฒ๋ง ํํฐ๋งํด์ ๋ค์ ์๋
}).catch((error) => {});
์์ ๊ฐ์ด ์ฝ๋ฐฑ์ ์ฌ์ฉํ๋ฉด ๊ฒฐ๊ณผ๊ฐ์ ๋ฐ๋ก ๋ฐ์์ผํ๊ณ , ์ฝ๋๊ฐ ์ง์ ๋ถํด์ง์ง๋ง, promise๋ฅผ ํตํด ๊ฒฐ๊ณผ๊ฐ์ ๋์ค์ ํ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค.
2-2. ๋น๋๊ธฐ๋ ๋์๊ฐ ์๋๋ค. ์์์ ๋ฌธ์ ๋ค.
ํ ๋ฒ ๋น๋๊ธฐ๋ ์์ํ ๋น๋๊ธฐ
๋น๋๊ธฐ๋ ๋์์ ๋ฌธ์ ๊ฐ ์๋๋ค. ์์์ ๋ฌธ์ ๋ค.
setTimeout(() => {
console.log('a');
}, 0);
setTimeout(() => {
console.log('b');
}, 1000);
setTimeout(() => {
console.log('c');
}, 2000);
์ ์ฝ๋๋ฅผ ๋ฐํ์ผ๋ก ํธ์ถ ์คํ์ ๊ทธ๋ ค๋ณด๋ฉด, ํ์ ์ด ์ฝ์ง ์์ ๊ฒ์ ์ ์ ์๋ค. ๊ทธ๋์ ๋น๋๊ธฐ๊ฐ ์ฌ์ฉ๋๋ ์ฝ๋์์๋ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ํตํด ์ถ๊ฐ์ ์ธ ๋ถ์์ด ํ์ํด์ง๋ค.
anonymous ๊น์ง ํธ์ถ ์คํ์์ ๋ชจ๋ ๊บผ๋ด์ง๊ณ ๋ ๋ค์์ ์ํ๋ฅผ ๊ทธ๋ฆผ์ผ๋ก ๊ทธ๋ ค๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
์ด๋, background๋ javascript๊ฐ ์๋๋ผ javascript ์์ง, ์ด์์ฒด์ ์ ๊ฐ์ ๋ ํฐ ๊ฐ๋ ์ด๋ผ๊ณ ์๊ฐํ์. ๊ทธ๋ฆฌ๊ณ background์ ๋ค์ด๊ฐ ๊ฒ์ ์ฌ๋ฌ๊ฐ๊ฐ ๋์์ ์คํ๋ ์ ์๋ค. ๋ํ์ ์ผ๋ก setTimeout์ ํ์ด๋จธ, ํ๋ก๋ฏธ์ค, ajax ์์ฒญ, ์ด๋ฒคํธ๋ฆฌ์ค๋ ๋ฑ์ด background์ ๋ค์ด๊ฐ๋ค.
background ์์ ์กด์ฌ๊ฐ ์๊ฐ์ ์ธ์ฃผ๊ณ , background์ ๋ค์ด์จ ๊ฒ๋ค์ ๊ฐ๊ฐ 0์ด, 1์ด, 2์ด ๋ค์ Macro Task Queue๋ฅผ ๊ฑฐ์ณ์ ํธ์ถ์คํ์ผ๋ก ์ฌ๋ผ๊ฐ๊ฒ ๋๋ค. ์ด๋ ์ด๋ฒคํธ ๋ฃจํ์ ์ญํ ์ด ํธ์ถ์คํ์ด ๋น์ด์์ ๋, ํ์์ ํจ์๋ฅผ ํธ์ถ์คํ์ผ๋ก ๋์ด์ฌ๋ ค ์ฃผ๋ ๊ฒ์ด๋ค.
2-3. ํ ๋ฒ ๋น๋๊ธฐ๋ ์์ํ ๋น๋๊ธฐ
micro task queue์๋ promise, process.nextTick์ด ๋ค์ด๊ฐ๊ณ ๋๋จธ์ง๋ macro๋ก ๋ค์ด๊ฐ๊ฒ ๋๋ค. ์ด๋ค task๊ฐ ๊ฑฐ์ ์๊ฐ ์ฐจ๊ฐ ๋์ง ์๋ ์ํ๋ก macro์ micro ํ์ ๊ฑฐ์ ๋์์ ๋ค์ด๊ฐ๊ฒ ๋๋ฉด, ๋ฌด์กฐ๊ฑด micro task๊ฐ ๋จผ์ ํธ์ถ ์คํ์ผ๋ก ์ฌ๋ผ๊ฐ๋ค. micro task queue๊ฐ ๊ฝ ์ฐจ์์ผ๋ฉด macro task๋ ์์ํ ์คํ์ด ๋์ง ์๋๋ค.
setTimeout(() => {
console.log('s');
}, 0);
Promise.resolve().then(() => {
console.log('p')
});
// p ์ถ๋ ฅ ํ s๊ฐ ์ถ๋ ฅ ๋จ
์์ ๊ฐ์ด setTimeout ์ฝ๋๊ฐ ์์ ์๊ณ , 0์ด ๋ค(์ฆ์) ์คํ์ด๋ผ๊ณ ํด๋ ํ๋ก๋ฏธ์ค๋ micro task queue์ ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์ p๊ฐ ๋จผ์ ์ถ๋ ฅ๋จ์ ํ์ธํ ์ ์๋ค.
let a = 2;
setTiemout(()=>{
a = 5;
console.log(a);
// 5๋ก ๋ณ๊ฒฝ๋ a๋ฅผ ์ฐ๋ ค๋ฉด ์ฌ๊ธฐ์์๋ง ์ฌ์ฉํ ์ ์๋ค.
}, 0);
console.log(a); // ์ฌ๊ธฐ์์๋ 5๋ก ๋ณ๊ฒฝ๋ a๋ฅผ ์ธ ์ ์๋ค
2-4. Promise์๋ ๋๊ธฐ ๋ถ๋ถ์ด ์๋ค!
let a = 2;
const p = new Promise((resolve, reject) => {
// ์ด ๋ถ๋ถ์ ๋๊ธฐ ๋ถ๋ถ!!
console.log("์ ์ผ ๋จผ์ ");
setTimeout(()=>{
a = 5;
console.log(a);
resolve(a):
}, 0);
});
console.log("๋ด์ง");
p.then((result) => {
console.log("result", result);
});
์ ์ฝ๋๋ฅผ ์คํ์ํค๋ฉด Promise ์์ ๋๊ธฐ ๋ถ๋ถ์์ console.log("์ ์ผ ๋จผ์ ")
๊ฐ ๋จผ์ ์คํ๋์ด ์ ์ผ ๋จผ์ ๊ฐ ์ถ๋ ฅ๋๊ณ , ๋ค์์ผ๋ก ๋๊ธฐ ๋ถ๋ถ์ธ console.log("๋ด์ง")
์ด ์คํ๋์ด ๋ด์ง์ด ์ถ๋ ฅ๋๋ค. ๋ค์์ผ๋ก setTimeout์ console.log(a)
์ Promise then์ console.log(result)
๋ background์ ์๋ค๊ฐ ๋ชจ๋ ํธ์ถ์คํ์ด ๋น์์ง ํ์ micro task queue์ ์๋ console.log(result)
๊ฐ ๋จผ์ ์คํ๋๊ณ console.log(a)
๊ฐ ์คํ๋๋ค.
2-5. async/await, Promise๋ก ๋ฐ๊พธ๊ธฐ
let a = 3;
const p = new Promise((resolve, reject)=>{
a = 5;
resolve(a);
});
p.then((result) => {
console.log('result', result);
}).then(() => {
}).catch(() => {
}).then(() => {
}).catch(() => {
}).then(() => {
}).catch(() => {
});
์ ์ฝ๋์ ๊ฐ์ด catch๋ ๊ผญ ๋งจ ๋์ ๋ถ์ด๋ ๊ฒ์ด ์๋๋ผ ์ค๊ฐ์ ๋ถ์ฌ์ค๋ ๋๋ค.
let a = 3;
const p = new Promise((resolve, reject)=>{
a = 5;
resolve(a);
});
p.then((result) => {
console.log('result', result);
return 1;
}).then((result) => {
console.log(result); // 1
}).then((result) => {
console.log(result); // undefined - ํจ์์ ๋ฆฌํด๊ฐ์ด ์์ผ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก undefined๋ฅผ ๋ฆฌํด
})
p.then((result) => {
console.log('result', result);
return Promise.resolve(1);
}).then((result) => {
console.log(result); // 1 - promise๊ฐ resolve๋ ๊ฐ
})
async function a() {
const a = await 1;
const b = await Promise.resolve(1); // ๋ง์ฐฌ๊ฐ์ง๋ก promise๊ฐ resolve๋ ๊ฐ์ด ์ ์ฅ๋จ
}
๋ณ์ = await ํ๋ก๋ฏธ์ค;
์ธ ๊ฒฝ์ฐ ํ๋ก๋ฏธ์ค๊ฐ resolve๋ ๊ฐ์ด ๋ณ์์ ์ ์ฅ๋๊ณ , ๋ณ์ await ๊ฐ;
์ธ ๊ฒฝ์ฐ ๊ทธ ๊ฐ์ด ๋ณ์์ ์ ์ฅ๋๋ค.
async function a() {
const a = await 1;
console.log('a', a);
console.log('hmm');
await null;
const b = await Promise.resolve(1);
console.log('b', b);
}
์ ์ฝ๋๋ฅผ Promise๋ก ๋ฐ๊ฟ๋ณด์. await์ด then์ด๋ผ๊ณ ์๊ฐํ๊ณ , await์ ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ์ด๋ผ๋ฉด Promise์์๋ ์ผ์ชฝ์์ ์ค๋ฅธ์ชฝ, ์์์ ์๋๋ก๋ผ๊ณ ์๊ฐํ๋ฉด ์ดํดํ๊ธฐ ์ฝ๋ค. ์์ ์๋์ ์ฝ๋๊ฐ 1๋1๋ก ๋์๋๋ ๊ฐ๋ ์ด ์๋๋ผ ํธ์์ ์ํด ๋ณํํ๋ ์ ์ ์ ์ํ์.
Promise.resolve(1)
.then((a) => {
console.log('a', a);
console.log('hmm');
return null;
})
.then(() => {
return Promise.resolve(1);
})
.then((b) => {
console.log('b', b);
})
์์ ๊ฐ์ด ๋ณํํ๋ฉด ์๋์ ์ฝ๋๋ฅผ ์๊ฐํํด์ ๋ถ์ํ๊ธฐ์ ํธํด์ง๋ค.
function delayP(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms);
});
}
async function a() {
const a = await 1;
console.log('a', a);
console.log('hmm');
await null;
const b = await Promise.resolve(1);
console.log('b', b);
return a+b;
}
a().then((result) => {
console.log(result);
});
์ ์ฝ๋์์ async function์ ๋ง๋๋ฉด ๋ถ์ํ๊ธฐ๊ฐ ๊น๋ค๋กญ๋ค. ๊ทธ๋์ ์ด๋ Promise๋ก ๋ณํํ๋ฉด ๋ถ์์ด ํธํด์ง๋ค.
2-6. ๋ฌด์ง์ฑ await ์ฐ๋ฌ์์ฐ๊ธฐ ๊ธ์ง!
function delayP(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms);
});
}
async function a() {
await delayP(3000); // 3์ด
await delayP(6000); // 6์ด
await delayP(9000); // 9์ด
}
์์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ฉด, a๋ฅผ ์คํํ์ ๋ 18์ด๊ฐ ๊ฑธ๋ฆฌ๋ ์ฝ๋๊ฐ ๋๋ค.
function delayP(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms);
});
}
async function a() {
const p1 = delayP(3000); // 3์ด
const p2 = delayP(6000); // 6์ด
const p3 = delayP(9000); // 9์ด
await Promise.all([p1, p2, p3]);
}
ํ์ง๋ง ์ด๋ ๊ฒ ์์ ํ๊ฒ ๋๋ฉด a๋ฅผ ์คํํ์ ๋ ๋ํฉ 9์ด ๋ฐ์ ๊ฑธ๋ฆฌ์ง ์๋ ์ฝ๋๊ฐ ๋๋ค.
์ข ๋ ์ค์ ์์ ๋ฒํ ์ํฉ์ ์ฝ๋๋ก ์์๋ฅผ ๋ค๋ฉด ์๋์ ๊ฐ๋ค.
async createPost() {
const post = await db.getPost();
if (post) {
res.status(403).send("์ด๋ฏธ ๊ฒ์๊ธ์ด ์กด์ฌํฉ๋๋ค.");
} else {
await db.createPost(); // ๊ฒ์๊ธ ์์ฑ
await db.userIncrementPostCount(); // ์ฌ์ฉ์์ ์์ฑ๊ธ ์นด์ดํธ 1 ์ฌ๋ฆผ
await db.createNoti(); // ๊ฒ์๊ธ ์์ฑ ์๋ฃ ์๋ฆผ
}
}
์์ฑ๊ธ ์นด์ดํธ 1 ์ฌ๋ฆฌ๊ธฐ, ๊ฒ์๊ธ ์์ฑ ์๋ฃ ์๋ฆผ์ ๊ผญ ์์ฐจ์ ์ผ๋ก ํ ํ์๊ฐ ์์๊น? ์ ๋ ๊ฒ ๊ผญ ์์ฐจ์ ์ผ๋ก ์คํ๋์ด์ผ ํ ํ์๊ฐ ์๋ ๊ฒ๋ค์ ์์ฒญ์ ๋์์ ๋ณด๋ด๊ณ , Promise.all
๋ก ์ฒ๋ฆฌํด์ฃผ๋ฉด ์๋ต์๊ฐ์ด ์ข ๋ ์ค์ด๋ค ์ ์๋ค.
2-7. ํ๋ก๋ฏธ์ค ๋ค์ํ ํ์ฉ
const results = await Promise.all([p1, p2, p3]);
results.map(async () => {
await result์กฐ์(); // p1, p2, p3์ result์ ๋ํด์ ์กฐ์์ด ๋์์ ๊ฐํด์ง
}, []);
for (let result of results) {
await result์กฐ์(); // p1 ๋๋ ํ p2 ๋๋ ํ p3
}
GPT๊ฐ ๋ง๋ค์ด์ค ์์ ์ฝ๋
์๋์ ์์ ๋ฅผ ํตํด map๊ณผ for of ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ๋ํ ์ฐจ์ด๋ฅผ ํ์คํ๊ฒ ๋๋ ์ ์๋ค.
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const result์กฐ์ = async (result) => {
await delay(1000); // 1์ด ๋์ ๋๊ธฐ
return result * 2; // ๊ฒฐ๊ณผ๋ฅผ 2๋ฐฐ๋ก ๋ง๋ญ๋๋ค.
};
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);
async function example() {
const results = await Promise.all([p1, p2, p3]);
console.time('Using map');
const doubledResultsWithMap = await Promise.all(results.map(async result => {
return await result์กฐ์(result);
}));
console.timeEnd('Using map');
console.time('Using for...of');
const doubledResultsWithForOf = [];
for (let result of results) {
doubledResultsWithForOf.push(await result์กฐ์(result));
}
console.timeEnd('Using for...of');
console.log('Results with map:', doubledResultsWithMap);
console.log('Results with for...of:', doubledResultsWithForOf);
}
example();
2-8. ํด๋ก์ (closure) ๋ถ์
ํด๋ก์ ๋ ํจ์์ ํจ์ ์ธ๋ถ์ ์๋ ๋ณ์์์ ๊ด๊ณ๋ค.
ํด๋ก์ ๋ฌธ์ -> ์ค์ฝํ, ๋น๋๊ธฐ, var
ํด๋ก์ ๊ฐ ๋ฌธ์ ์ธ ๊ฒ ์๋๋ผ, ํด๋ก์ ๋ฅผ ์ฌ์ฉํด์ ํด๊ฒฐํ๋ ๋ฌธ์
for๋ฌธ(๋ฐ๋ณต๋ฌธ)๊ณผ ๋น๋๊ธฐ๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ฉด ์ข ์ข ๋ฐ์
๋ฌธ์ ์ํฉ : var๊ณผ for๊ณผ ๋น๋๊ธฐ์ ํ์์ ์ฝ๋ผ๋ณด(...)
function a() {
for (var i = 0; i < 5; i++) {
setTimeout(()=>{
console.log(i);
}, i * 1000);
}
}
// 5๊ฐ 5๋ฒ ์ถ๋ ฅ๋จ
๋ฌธ์ ๊ฐ ๋๋ ์ด์ ๋ก ์ฒซ๋ฒ์งธ, var์ ๋ธ๋ก ์ค์ฝํ๋ฅผ ๋ฐ๋ฅด์ง ์๊ณ ํจ์ ์ค์ฝํ๋ฅผ ๋ฐ๋ฅด๊ธฐ ๋๋ฌธ์ด๋ค. ์ฆ i๋ ํจ์ a์ ๋ค์ด์๊ฒ ๋๋ค. ๋๋ฒ์งธ, setTimeout์ด ๋ค์ฏ๋ฒ ์คํ๋๋ ์๊ฐ i๋ 0, 1, 2, 3, 4๋ฅผ ๊ฑฐ์น๊ณ i++์ด ํ ๋ฒ ๋ ์คํ๋์ด 5๊ฐ ๋๊ณ i < 5๊ฐ false๊ฐ ๋์ด ๋ฐ๋ณต๋ฌธ์ด ๋ฉ์ถ๋ค.
ํด๊ฒฐ๋ฐฉ๋ฒ 1. var์ ์ ์งํด์ผ ํ ๋ => ์ฆ์์คํํจ์(IIFE)๋ก ํด๋ก์ ์์ฑ
function a() {
for (var i = 0; i < 5; i++) {
(function(j){
setTimeout(()=>{
console.log(j);
}, i*1000)
})(i);
}
}
// 0, 1, 2, 3, 4๊ฐ ์์ฐจ์ ์ผ๋ก ์ถ๋ ฅ๋จ
์ฆ์ ์คํํจ์๋ ์ ์ธ์ด์ ํธ์ถ์ด๋ฏ๋ก j๊ฐ ์์ฐจ์ ์ผ๋ก 0, 1, 2, 3, 4์ ๊ฐ์ ๊ฐ์ง๊ฒ ๋๋ค.
ํด๊ฒฐ๋ฐฉ๋ฒ 2. var์ let์ผ๋ก ์์
function a() {
for (let i = 0; i < 5; i++) {
setTimeout(()=>{
console.log(i);
}, i * 1000);
}
}
var์ a์ ์ํ์ง๋ง, let์ผ๋ก ๋ฐ๊พธ๊ฒ๋๋ฉด for๋ฌธ์ ์ํ๊ธฐ ๋๋ฌธ์ for๋ฌธ์ ๊ฐ ์ค์ฝํ 5๊ฐ์์์ i๊ฐ(0, 1, 2, 3, 4)์ ์ถ๋ ฅํ๊ฒ ๋๋ค.