Contents
PromisePromise
ํด๋น ๊ฒ์๋ฌผ์ Javascript Deep Dive๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ ๋์ต๋๋ค.
์ ํต์ ์๋ฐ์คํฌ๋ฆฝํธ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํด ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฌ์ฉํ๋ค.
ES6์์ ๋น๋๊ธฐ ํจ์๋ ๋์์ ์ฒ๋ฆฌ๋ฅผ ์ํ ํจํด์ผ๋ก ES6์์ Promise๋ผ๋ ๊ฐ๋
์ ๋์
ํ๋ค.
๋น๋๊ธฐ ํจ์๋ ๋ฌด์์ผ๊น?
Javascript Deep Diev์์ ์ด๋ ๊ฒ ๋งํ๋ค.
๋น๋๊ธฐ ํจ์๋ฅผ ํธ์ถํ๋ฉด ํจ์ ๋ด๋ถ์ ๋น๋๊ธฐ๋ก ๋์ํ๋ ์ฝ๋๊ฐ ์๋ฃ๋์ง ์์๋ค๊ณ ํด๋ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ ์ข ๋ฃ๋๋ค. ์ฆ, ๋น๋๊ธฐ ํจ์ ๋ด๋ถ์ ๋น๋๊ธฐ๋ก ๋์ํ๋ ์ฝ๋๋ ๋น๋๊ธฐ ํจ์๊ฐ ์ข ๋ฃ๋ ์ดํ์ ์๋ฃ๋๋ค. ๋ฐ๋ผ์ ๋น๋๊ธฐ ํจ์ ๋ด๋ถ์ ๋น๋๊ธฐ๋ก ๋์ํ๋ ์ฝ๋์์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ธ๋ถ๋ก ๋ฐํํ๊ฑฐ๋ ์์ ์ค์ฝํ์ ๋ณ์์ ํ ๋นํ๋ฉด ๊ธฐ๋ํ ๋๋ก ๋์ํ์ง ์๋๋ค.
Persistent Issues of Asynchronous Processing
- ๋น๋๊ธฐ ๋์์ ์ ์ดํ ์ ์์
setTimeout ํจ์๋ ๋น๋๊ธฐ๊ณ ๋น๋๊ธฐ์ธ ์ด์ ๋ callback ํจ์์ ํธ์ถ์ด ๋น๋๊ธฐ๋ก ๋์ํ๋ค.
let g = 0; setTimeout(() => { g = 100; }, 0); console.log(g); // 0
์๋์ชฝ console์ด 100์ ๊ฐ๋ฆฌํฌ ๊ฒ์ ์์ํ๊ณ ์์ฑํ๊ฒ ์ง๋ง, setTimeout์ ๋น๋๊ธฐ ํจ์์ด๊ธฐ ๋๋ฌธ์ callback ํจ์๋ ๋์์ด ์๋ฃ๋ ์์ ์ธ
console.log(g)
๊ฐ ์คํ๋ ํ์ ๋ด๋ถ callback ํจ์๊ฐ ์คํ๋๋ค.- callback ์ง์ฅ
๋ ์ ํต์ Javascript์์๋ ์ด๋ฌํ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋๋ฌธ์ callback ์ง์ฅ์ด ๋ฐ์ํ๊ณค ํ๋๋ฐ, ์์ฆ ES6์ async/await ๋ฌธ๋ฒ์ด ๋ณดํธํ๋ ์ดํ๋ก ๊ฐ๋ฐ์ ์
๋ฌธํ ์ฌ๋์ด๋ผ๋ฉด ๊ฒช์ง ๋ชปํ์ ๊ฒ์ด๋ค.
function stepOne(callback) { setTimeout(function () { console.log("Step One completed"); callback(); }, 3000); } function stepTwo(callback) { setTimeout(function () { console.log("Step Two completed"); callback(); }, 3000); } stepOne(function () { stepTwo(function () { console.log("All steps completed"); }); }); // Step One completed // Step Two completed // All steps completed
์ด๋ฐ์์ผ๋ก, callback์ ์์ ๋ณด์ฅ์ ์ํด ๋น๋๊ธฐ ํจ์๊ฐ ์คํ๋๋ฉด callback ํจ์๋ฅผ ์คํ์ํค๊ณ โฆ ๋ ์คํ์ด ์๋ฃ๋๋ฉด callback์ ์คํ์ํค๊ณ .. ๋์๋ callback ์ง์ฅ์ ๋น ์ง๊ฒ ๋๋ค.
- Error Handling์ ์ด๋ ค์
try { setTimeout(() => { throw new Error("ERROR!"); }, 1000); } catch (e) { console.log("CATCH ERROR:", e); } // Error: ERROR!
์ ๊ฐ์ ๋ก ๋ฐ์์ํจ ์๋ฌ๋ catch ๋ธ๋ก์์ ์คํ๋์ง ์๋๋ค.
setTimeout ํจ์๊ฐ ํธ์ถ๋๋ฉด ํจ์์ ์คํ ์ปจํ
์คํธ๊ฐ ์์ฑ๋๊ณ call stack์ push๋ ํ ์คํ๋๋ค. setTimeout์ ๋น๋๊ธฐ ํจ์๊ธฐ ๋๋ฌธ์ callback ํจ์๊ฐ ํธ์ถ๋๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ ์ข
๋ฃ๋ ํ ์ฝ์คํ์์ ์ ๊ฑฐ๋๋ค.
์ค์ ํด ๋ 1000ms์ธ 1์ด๊ฐ ์ง๋๊ณ ๋๋ฉด, setTimeout ํจ์์ callback ํจ์๋ task ํ๋ก push๋ ํ call stack์ด ๋น์ด์ก์ ๋ Event loop์ ์ํด call stack์ผ๋ก push๋์ด ์คํ๋๋ค.
callback ํจ์๊ฐ ์คํ๋๋ ์์ ์ ์ด๋ฏธ, ํธ์ถ์์ธ setTimeout ํจ์๋ call stack์์ ์ ๊ฑฐ๋ ์ํ๋ค. ์ด ๋ง์ callback์ ํธ์ถ์(caller)๊ฐ setTimeout์ด ์๋๋ผ๋ ์๋ฆฌ์ด๋ฉฐ, ํ์ฌ ์คํ๋ ํ์ผ์ ์ปจํ
์คํธ์ ํ์ ์ปจํ
์คํธ๊ฐ setTimeout์ ์คํ ์ปจํ
์คํธ์ฌ์ผ ํ๋๋ฐ callback์ด ํฌํจ๋์ง ์์๋ค๋ ๊ฒ์ setTimeout์ ํ์ ์คํ์ปจํ
์คํธ๊ฐ ์๋๋ผ๋ ๊ฒ์ด๋ค.
์๋ฌ๋ ํธ์ถ์ ๋ฐฉํฅ์ผ๋ก ์ ํ๋๋ค. ๊ธฐ์กด ํจ์์ ์คํ์ปจํ
์คํธ(setTimeout)๊ฐ ํธ์ถ์๊ฐ ์๋๊ธฐ ๋๋ฌธ์ catch block์ ํฌํจ๋์ง ์์ ๊ฒ์ด๋ค.
๋จ์ํ๊ฒ ๋งํ๋ฉด, ์คํ์ด ์๋ฃ๋๋ ์์ ์ callback์ด ์คํ๋์ง ์์๊ธฐ ๋๋ฌธ์ catch์์ ์ธ์ํ์ง ๋ชปํ ๊ฒ์ด๋ค.
Promise
promise๋ ES6์์ ๋์
๋ ๋ฌธ๋ฒ์ด๋ค.
์ค์ ๋ก stackoverflow๋ reddit ๊ฐ์ ์ฌ์ดํธ๋ค์ ๋งค์ฐ ์ค๋๋ 8๋
์ด์๋ ๊ณผ๊ฑฐ ๊ฒ์๋ฌผ๋ค์ ๋ณด๋ฉด ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ๊ดํ ์ง๋ฌธ์ด ์๋นํ ๋ง๊ณ , 2018๋
์ด๋ 2019๋
์ฏค์๋ async / await์ ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํ๋์ง์ ๋ํ ์ง๋ฌธ์ด ๋ ๋ง๋ค. ๊ทผ๋์๋ ES6์ธ Arrow function์ด๋ async / await ๋ฑ promise ๋ฌธ๋ฒ๋ค์ด ๋ณดํธํ๋์ด ์ฝ๊ฒ ์ฌ์ฉํ๊ณ ์์ง๋ง, ๊ณผ๊ฑฐ์ Javascript ์ํ๊ณ๋ ์์ฃผ ํผ๋์ค๋ฌ์ ๋ ๊ฒ ๊ฐ๋ค.
- Promise ์์ฑ์
- pending
- fulfilled
- rejected
Promise ์์ฑ์ ํจ์๊ฐ ์ธ์๋ก ์ ๋ฌ๋ฐ์ callback ํจ์ ๋ด๋ถ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์คํํ๋ค.
๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํ๋๋ฉด resolve ํจ์๋ฅผ ํธ์ถํ๊ณ , ์คํจํ๋ฉด reject ํจ์๋ฅผ ํธ์ถํ๋ค.
const promise = new Promise((resolve, reject) => { const success = true; if (success) { return resolve("Operation successful"); } else { return reject("Operation failed"); } }); console.log(promise); // Promise { <pending> }
Promise๋ ๋ค์์ ์ํ๋ก ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ ๋ณด๋ฅผ ํ์ํ๋ค.
๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์์ง ์ํ๋์ง ์์ ์ํ, Promise๊ฐ ์์ฑ๋ ์งํ
๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ํ๋ ์ํ(์ฑ๊ณต), Resolve ํจ์ ํธ์ถ
๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ํ๋ ์ํ(์คํจ), Reject ํจ์ ํธ์ถ
fulfilled ๋๋ rejected๋ ์ํ๋ฅผ settled ์ํ๋ผ๊ณ ํ๋ค. settled ์ํ๋ก ๋ณํํ ํ์๋ ๋ค๋ฅธ ์ํ๋ก ๋ณํํ ์ ์๋ค.
function stepOne(callback) { setTimeout(function() { console.log("Step One completed"); callback(); }, 3000); } function stepTwo(callback) { setTimeout(function() { console.log("Step Two completed"); callback(); }, 3000); } function stepThree(callback) { setTimeout(function() { console.log("Step Three completed"); callback(); }, 3000); } stepOne(function() { stepTwo(function() { stepThree(function() { console.log("All steps completed"); }); }); });
- ํ์ ์ฒ๋ฆฌ ๋ฉ์๋
- then
- catch
- finally
์ฒซ ๋ฒ์งธ callback ํจ์๋ Promise๊ฐ ์ฑ๊ณต ํ์ ๋, ๋ ๋ฒ์งธ callback์ Promise๊ฐ ์คํจ ํ์ ๋ ๋ฐ๋๋ค.
const promise = new Promise((resolve, reject) => { const success = true; if (success) { return resolve("Operation successful"); } else { return reject("Operation failed"); } }).then((v) => { console.log("Resolve:", v); }, (e) => { console.log("Reject:", e); }); // Resolve: Operation successful const promise = new Promise((resolve, reject) => { const success = false; if (success) { return resolve("Operation successful"); } else { return reject("Operation failed"); } }).then((v) => { console.log("Resolve:", v); }, (e) => { console.log("Reject:", e); }); // Reject: Operation failed
Promise๊ฐ rejected๋ ์ํ์ธ ๊ฒฝ์ฐ ํธ์ถ๋๋ฉฐ, then๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ธ์ ๋ Promise๋ฅผ ๋ฐํํ๋ค. ์๋ฌ ํธ๋ค๋ง์ ์ํด ์ฃผ๋ก ์ฌ์ฉ๋๋ค.
Promise์ fulfilled๋ rejected์ ์๊ด์์ด ๋ฌด์กฐ๊ฑด ํ ๋ฒ ํธ์ถ๋๋ค. ์ธ์ ๋ Promise๋ฅผ ๋ฐํํ๋ค.
์ด๋ฌํ callback ์ฒ๋ฆฌ ๋ฉ์๋๋, ์ฝ๋ ์ ์ด์ ์ง๋ํ ์ํฅ์ ๋ผ์ณค์ง๋ง ์ด ๋ํ callback ํจํด์ด๊ธฐ ๋๋ฌธ์ ๊ฐ๋
์ฑ์ด ์ข์ง ์๋ค.
- Promise Static ๋ฉ์๋
- Promise.resolve / Promise.reject
- Promise.all
- Promise.race
- Promise.allSettled
const resolve = Promise.resolve([1,2,3] resolve.then(console.log) // [1,2,3] const reject = Promise.reject(new Error('Error!')); reject.catch(console.log) // Error: Error!
์ธ์๋ก ์ ๋ฌ๋ฐ์ ๊ฐ์ resolve๋ reject๋ก ๋ํํ์ฌ Promise๋ฅผ ์์ฑํ๋ ๋ฌธ๋ฒ์ด๋ค.
์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ชจ๋ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ ๋ ์ฌ์ฉํ๋ค.
const promise1 = () => { return new Promise(resolve => setTimeout(() => { resolve(1) }, 3000)) }; const promise2 = () => { return new Promise(resolve => setTimeout(() => { resolve(2) }, 2000)) } const promise3 = () => { return new Promise(resolve => setTimeout(() => { resolve(3) }, 1000)); }; Promise.all([ promise1(), promise2(), promise3() ]).then((resolve) => { console.log("Resolve:", resolve); }); // Resolve: [ 1, 2, 3 ]
Promise.all์ Promise๋ฅผ ๊ฐ์ง ๊ฐ์ ๋ฐฐ์ด ๋ฑ์ ์ดํฐ๋ฌ๋ธ์ ์ธ์๋ก ์ ๋ฌ๋ฐ๋๋ค.
์ ๋ฌ๋ฐ์ ๋ชจ๋ Promise๊ฐ fulfilled ์ํ๊ฐ ๋๋ฉด ๋ชจ๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์ด์ ์ ์ฅํด ์๋ก์ด Promise๋ฅผ ๋ฐํํ๋ค.
์ฒซ๋ฒ์งธ promise1์ด ์ ์ผ ๋์ค์ fulfilled ์ํ๊ฐ ๋๋ค๊ณ ํ๋๋ผ๋ Promise.all์ ์ฒซ ๋ฒ์งธ ํ๋ก๋ฏธ์ค๊ฐ ์ฒ๋ฆฌํ ๊ฒฐ๊ณผ๋ถํฐ ์ฐจ๋ก๋๋ก ๋ฐฐ์ด์ ์ ์ฅํ๋ค.
์ฆ, ์ฒ๋ฆฌ ์์๊ฐ ๋ณด์ฅ๋๋ค.
ํํธ Promise๊ฐ ํ๋๋ผ๋ rejected๊ฐ ๋๋ค๋ฉด ๋๋จธ์ง promise๊ฐ fulfilled๊ฐ ๋๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ ์ข
๋ฃํ๋ค.
Promise.all๊ณผ ๋น์ทํ๊ฒ ๋์ํ์ง๋ง, ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ fulfilled ์ํ๊ฐ ๋๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด ์๋ ๊ฐ์ฅ ๋จผ์ fulfilled ์ํ๊ฐ ๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ resolveํ๋ ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
... Promise.race([ promise1(), promise2(), promise3() ]).then((resolve) => { console.log("Resolve:", resolve); }); // Resolve: 3
Promise๊ฐ ๋ชจ๋ settled ์ํ๊ฐ ๋๋ฉด ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์ด๋ก ๋ฐํํ๋ค.
Promise.all์ด ๋ชจ๋ resolve๋์ผ ํ๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ๊ณผ ๋ฌ๋ฆฌ, allSettled๋
rejected๋ ์ํ๋ ๋ฐํํ๋ค.
๋ง์ฝ rejected๋ ๊ฒฝ์ฐ reason property๋ฅผ ๊ฐ์ง๋ค.
const promise1 = () => { return new Promise(resolve => setTimeout(() => { resolve(1) }, 3000)) }; const promise2 = () => { return new Promise(resolve => setTimeout(() => { resolve(2) }, 2000)) } const promise3 = () => { return new Promise((resolve, reject) => { return reject(new Error("Reject ERROR")) }); }; Promise.allSettled([ promise1(), promise2(), promise3() ]).then((resolve) => { console.log("Resolve:", resolve); }).then(e => { console.log("Error:", e); }); // Resolve: [ // { status: 'fulfilled', value: 1 }, // { status: 'fulfilled', value: 2 }, // { // status: 'rejected', // reason: Error: Reject ERROR // ... // at node:internal/main/run_main_module:23:47 // } // ] // Error: undefined
async/await
async/await์ Promise ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ค.
then/catch/finally๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋๊ธฐ์ ์ผ๋ก ๋์ํ๋ ๊ฒ ์ฒ๋ผ Promise์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
const func = () => { const promise = new Promise(resolve => setTimeout(() => { resolve(1) }, 3000)); return promise }; (async() => { const resolve = await func(); console.log("Resolve:", resolve); })();
- async
await ํค์๋๋ ๋ฐ๋์ async function ๋ด๋ถ์์ ์ฌ์ฉํด์ผ ํ๋ค.
async function์ async ํค์๋๋ฅผ ํตํด ์ ์ํ๋ฉฐ ์ธ์ ๋ promise๋ฅผ ๋ฐํํ๋ค.
async ํจ์ inner์ ์คํ ์คํฌ๋ฆฝํธ๊ฐ ์ค์ promise๋ฅผ ๋ฐํํ์ง ์๋๋ผ๋, async๋ ์ธ์ ๋ ๋ฐํ๊ฐ์ resolveํ๋ promise๋ฅผ ๋ฐํํ๋ค.
- await
await์ Promise๊ฐ settled ์ํ๊ฐ ๋ ๋๊น์ง ๋๊ธฐํ๋ค settled๊ฐ ๋๋ฉด promise๊ฐ resolveํ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
await์ ๋ชจ๋ ํค์๋์ ์ฌ์ฉํ๋ ๊ฒ์ ์ฃผ์ํด์ผ ํ๋๋ฐ, ๋ง์ฝ ์ ํ Promise๊ฐ ์ข
๋ฃ๋ ๋๊น์ง ๋ง์ ์๊ฐ์ด ์์๋๋ค๋ฉด, ์ ํ Promise์ ์๋ฃ ์์ ์ ๋ค์ Promise๊ฐ ๊ธฐ๋ค๋ฆฌ๊ธฐ ๋๋ฌธ์ธ๋ฐ ์ด๋ด ๊ฒฝ์ฐ์๋ Promise.all์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
- Error Handling
async ํจ์ ๋ด์์ catch ๋ฌธ์ ์ฌ์ฉํด์ error ์ฒ๋ฆฌ๋ฅผ ํ์ง ์์ผ๋ฉด async ํจ์๋ ๋ฐ์ํ ์๋ฌ๋ฅผ rejectํ๋ promise๋ฅผ ๋ฐํํ๋ค.
๊ทธ๋ ๋ค๋ฉด, ๋ง์ง๋ง ์์ ๋ก Promise์ ์คํ ์์์ ๋ํด์ ์์๋ณด๋ฉด
console.log("Start"); // 1 function delay(time) { return new Promise(resolve => setTimeout(resolve, time)); } async function asyncOperation() { await delay(2000); console.log("Async operation completed"); // 5 } const firstPromise = new Promise(resolve => { setTimeout(() => { console.log("First promise resolved"); // 4 resolve(); }, 3000); }); const secondPromise = new Promise(resolve => { setTimeout(() => { console.log("Second promise resolved"); // 3 resolve(); }, 1000); }); async function main() { await firstPromise; await secondPromise; await asyncOperation(); console.log("All promises and async operations completed"); // 6 } main(); console.log("End"); // 2
์ฌ๊ธฐ์ ๋ค ์ ์๋ ์๋ฌธ์, ์ firstPromise์ setTimeout์ callback์ด ๋จผ์ ์คํ์๋๊ณ , second๊ฐ ๋จผ์ ์คํ ๋๋์ง ์ผ ๊ฒ์ด๋ค.
์์์ ์ค๋ช
ํ ๊ฒ์ฒ๋ผ ์ฝ๋์ ๊ตฌ์กฐ์ ๋ฐ๋ฅด๋ฉด
await firstPromise;
๊ฐ ๋จผ์ ์คํ๋์ด์ผ ํ ๊ฒ์ผ๋ก ์์๋์ง๋ง, secondPromise
์ setTimeout ํจ์์ ์๊ฐ์ด ๋ ์งง์์ ํด๋น Promise๊ฐ ๋จผ์ ์๋ฃ๋ ๊ฒ์ด๋ค.๋น๋๊ธฐ ์๋ฌ ํธ๋ค๋ง์ ์ด๋ ค์์์ ์ค๋ช
ํ๋ ๊ฒ ์ฒ๋ผ, setTimeout ์์ฒด๋ ๋น๋๊ธฐ ํจ์๊ณ Promise์ ์คํ์ ์ด๋ฏธ ์๋ฃ ๋๊ธฐ ๋๋ฌธ์, task queue์ ๋น ์ ธ ์๋ callback ํจ์๊ฐ call stack์ ์์ฐจ์ ์ผ๋ก ์คํ๋๋ ๊ฒ ๋ฟ ์คํ ์์ฒด๋ ์๋ํ ๋๋ก ์คํ๋๋ค.
๋ง์ฝ ์ ์ฝ๋๋ฅผ ์ ๋ง๋ก ๋์ ์์ฒด๋ฅผ ์์๋๋ก ์คํ์ํค๊ณ ์ถ๋ค๋ฉด resolve๋ฅผ ์ธ์๋ก ๋ฐ์ promise๋ฅผ returnํ๋
console.log("Start"); function delay(time) { return new Promise(resolve => setTimeout(resolve, time)); } async function asyncOperation() { await delay(2000); console.log("Async operation completed"); } const firstPromise = async() => { await delay(3000); console.log("First Promise resolved"); } const secondPromise = async() => { await delay(1000); console.log("Second Promise resolved"); } async function main() { await firstPromise(); await secondPromise(); await asyncOperation(); console.log("All promises and async operations completed"); } main(); console.log("End");
delayํจ์๋ฅผ ์ด์ฉํด ์ด๋ ๊ฒ ๋ฐ๊ฟ ์ค๋ค๋ฉด, Promise ๋ฅผ ์ํ๋๋๋ก ๋์์ํฌ ์ ์๋ค.
Share article