๐Ÿ“ŒLanguage/JavaScript

TIL) Async function(๋น„๋™๊ธฐ ํ•จ์ˆ˜)์™€ Promise, Async์—์„œ ์˜ค๋ฅ˜ ์žก๊ธฐ

hellohailie 2022. 6. 4. 15:59

 

Async function๋Š” ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์•„์ฃผ ๊น”๋”ํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋„๋ก ๋•๋Š” ํ•จ์ˆ˜์ด๋‹ค. (Promiseํ•จ์ˆ˜๋ณด๋‹ค ๋” ๊น”๋”!)

Promise ์œ„์— ์ ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— Promise์— ๋ฟŒ๋ฆฌ๋Š” ์„คํƒ•์ด๋ผ๊ณ ๋„ ํ•œ๋‹ค. 

 

์ฐธ๊ณ  **IE์—์„œ๋Š” ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. **

 


async & await

async ์ž์ฒด๊ฐ€ ํ•จ์ˆ˜๋ฅผ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋กœ ์„ ์–ธํ•˜๋Š” ํ‚ค์›Œ๋“œ์ด๋‹ค. 

ํ•จ์ˆ˜ ์•ž์— async๋ฅผ ์ž…๋ ฅํ•ด์„œ ํ•จ์ˆ˜๋ฅผ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋กœ ์„ ์–ธํ•˜๋ฉด, ํ•จ์ˆ˜๋Š” ์ž๋™์œผ๋กœ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

 

โžฅ ๋นˆ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด undefined๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค. 

 

โžฅ ๋น„์–ด์žˆ๋Š” async ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Promise๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค. 

 

 

โžฅ ๋น„์–ด์žˆ๋Š” async ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Promise๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค. 

 

 

โžฅ async ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Promise๊ฐ€ ๋ฆฌํ„ด๋œ๋‹ค.  


Promise์˜ ์›๋ฆฌ

 

ํ•จ์ˆ˜๊ฐ€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ๋•Œ, resolved ์ƒํƒœ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค. 

 

 

const newFun = async () => {
    return 'LA LA LA LA'
}
newFun().then((data) => {
    console.log('PROMISE RESOLVED WITH:', data)
})

// ์ถœ๋ ฅ๊ฐ’
PROMISE RESOLVED WITH: LA LA LA LA
Promise {<fulfilled>: undefined}

โžฅ ์—ฌ๊ธฐ์„œ๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. 

๊ทธ๋ƒฅ ๋ฌธ์ž์—ด๋งŒ ์ถœ๋ ฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— async ํ•จ์ˆ˜๋ฅผ ์“ธ ์ด์œ ๊ฐ€ ์—†๋Š”๊ฑฐ๋‹ค 


Promise๊ฐ€ ์‹คํŒจ๋กœ ๋œจ๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋น„๋™๊ธฐ ํ•จ์ˆ˜์— ์˜ค๋ฅ˜๋ฅผ ๋˜์ง€๋ฉด ๋œ๋‹ค. 

 

const newFun = async () => {
	throw new Error('UH OH')
    return 'LA LA LA LA'
}

๐Ÿ‘‡ ์ถœ๋ ฅ๊ฐ’

 

 

** ๋น„๋™๊ธฐ ํ•จ์ˆ˜(asyncํ•จ์ˆ˜)์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ๋ฉด Promise์˜ ์ƒํƒœ๋Š” ์‹คํŒจ๋กœ ๋œฌ๋‹ค. 

throw 'ERROR'

 


Async ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋กœ ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ• (๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๊ณผ์ •์€ ์—†๋‹ค. )

Promise๊ฐ€ ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜๋˜๊ณ , ๋‚ด๋ถ€์— ๊ฐ’์ด ์žˆ๋Š๋ƒ์— ๋”ฐ๋ผ ์„ฑ๊ณต๊ณผ ์‹คํŒจ๊ฐ€ ๊ฒฐ์ •๋˜๋Š”๋ฐ 
๋ฐ˜ํ™˜๊ฐ’์ด ์žˆ์œผ๋ฉด resolved๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ณ , ์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ’๊ณผ ํ•จ๊ป˜ rejected๊ฐ€ ๋œฌ๋‹ค. 

 

 

1. ์ธ์ž๋ฅผ ๋œ ๋„ฃ์—ˆ์„๋•Œ

const login = async (username, password) => {
	if(!username || !password) throw 'Missing Credentials'
    if(password === 'corgifeetarecute') return 'WELCOME!'
    throw 'Invalid Password'
}

login('alsltjsals')
	.then(msg => {
		console.log('LOGGED IN!')
    	console.log(msg)
	})
	.catch(err => {
		console.log('ERROR')
   	 console.log(err)
	})

๐Ÿ‘‡ ์ถœ๋ ฅ๊ฐ’

โžฅ ์ธ์ˆ˜๋ฅผ ๋‘ ๊ฐœ๋ฅผ ๋„ฃ์–ด์•ผํ•˜๋Š”๋ฐ, 'alsltjsals' ํ•˜๋‚˜๋งŒ ์ž…๋ ฅํ•ด์„œ ๋ˆ„๋ฝ๋˜์—ˆ๋‹ค๋Š” ๋ฌธ๊ตฌ๊ฐ€ ๋œฌ๋‹ค. 

 

 

 

2. ์กฐ๊ฑด์— ๋งž์ง€ ์•Š์„๋•Œ

 

const login = async (username, password) => {
	if(!username || !password) throw 'Missing Credentials'
    if(password === 'corgifeetarecute') return 'WELCOME!'
    throw 'Invalid Password'
}

login('alsltjsals', 'catiscute')
	.then(msg => {
		console.log('LOGGED IN!')
    	console.log(msg)
	})
	.catch(err => {
		console.log('ERROR')
   	 console.log(err)
	})

๐Ÿ‘‡ ์ถœ๋ ฅ๊ฐ’

 

โžฅ ์œ ํšจํ•˜์ง€ ์•Š์€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋„ฃ์–ด์„œ 'Invalid Password' ๊ฐ€ ์ถœ๋ ฅ๋œ๊ฑฐ๋‹ค. 

 

 

3. ์กฐ๊ฑด์— ๋งž์„๋•Œ

 

const login = async (username, password) => {
	if(!username || !password) throw 'Missing Credentials'
    if(password === 'corgifeetarecute') return 'WELCOME!'
    throw 'Invalid Password'
}

login('alsltjsals', 'corgifeetarecute')
	.then(msg => {
		console.log('LOGGED IN!')
    	console.log(msg)
	})
	.catch(err => {
		console.log('ERROR')
   	 console.log(err)
	})

๐Ÿ‘‡ ์ถœ๋ ฅ๊ฐ’

โžฅ ์•Œ๋งž์€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋„ฃ์–ด์„œ ๋กœ๊ทธ์ธ์ด ๋˜์—ˆ๋‹ค.

 

 


๋น„๋™๊ธฐ ํ•จ์ˆ˜ ์ฒ˜๋ฆฌ ๊ณผ์ •

Await ํ‚ค์›Œ๋“œ๋Š” ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์“ฐ๋ฉด์„œ ๋™๊ธฐ์ ์œผ๋กœ ๋ณด์ด๊ฒŒ ํ•ด์ค€๋‹ค. 

await ํ‚ค์›Œ๋“œ์˜ ์—ญํ• ์€ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ธ๋ฐ,

Promise๊ฐ€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ๋•Œ๊นŒ์ง€๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ ์œ„ํ•ด ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ์‹คํ–‰์„ ์ผ์‹œ ์ •์ง€์‹œํ‚จ๋‹ค. 

 

** ๋น„๋™๊ธฐ ํ•จ์ˆ˜์—์„œ๋งŒ ์ ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ASYNC & AWAIT๋Š” ํ•œ ์Œ์ด๋‹ค!

 

 

๐Ÿ‘‡ Promise๋ฅผ ์ƒ์„ฑํ•˜๊ณ  .then์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•

const delayedColorChange = (color, delay) => {
	return new Promise((resolve, reject) => {
    	setTimeout(() => {
        	document.body.style.backgroundColor = color;
            resolve();
        }, delay)
    })
}


delayedColorChange('red', 1000)             
	.then(() => delayedColorChange('orange', 1000))
    .then(() => delayedColorChange('yellow', 1000))
    .then(() => delayedColorChange('green', 1000))
    .then(() => delayedColorChange('blue', 1000))

 

๐Ÿ‘‡ ์œ„ ํ•จ์ˆ˜๋ฅผ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ์จ๋ณด์ž!

 

const delayedColorChange = (color, delay) => {
	return new Promise((resolve, reject) => {
    	setTimeout(() => {
        	document.body.style.backgroundColor = color;
            resolve();
        }, delay)
    })
}
    
async function rainbow() {
	await delayedColorChange('red', 1000)   // await ํ‚ค์›Œ๋“œ๋ฅผ ์“ฐ๋ฉด Promise๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ๋‚ผ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์ค€๋‹ค.
    await delayedColorChange('orange', 1000)
    await delayedColorChange('yellow', 1000)
    await delayedColorChange('green', 1000)
    await delayedColorChange('blue', 1000)
    console.log('ALL DONE');
}

๐Ÿ‘‡ 'ALL DONE'์€ ํŒŒ๋ž€์ƒ‰์ด ๋‚˜ํƒ€๋‚œ ํ›„์— ์ฝ˜์†”์ฐฝ์— ์ฐํžŒ๋‹ค.

 

โžฅ .then์„ ์“ฐ๊ฑฐ๋‚˜ ์ฝœ๋ฐฑ์„ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ๋ฐ˜ํ™˜๋œ ๊ฐ’์„ ์—ฐ๊ฒฐํ•  ํ•„์š”๋„ ์—†๋‹ค. 

 

 

rainbow().then(() => console.log('end of rainbow!'))

๐Ÿ‘‡ 'end of rainbow!' ๋Š” ํŒŒ๋ž€์ƒ‰์ด ๋‚˜ํƒ€๋‚œ ํ›„์— 'ALL DONE'๊ฐ€ ์ฐํžˆ๊ณ  ๋‚œ ๋’ค์— ๊ฑฐ์˜ ๋™์‹œ์— ์ฝ˜์†”์ฐฝ์— ์ž…๋ ฅ๋œ๋‹ค. 

 

 


๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋Š” Promise๊ฐ€ reject๋์„ ๋•Œ

 

const fakeRequest = (url) => {
	return new Promise((resolve,reject) => {
    	const delay = Math.floor(Math.random() * 4500) + 500;
        setTimeout(() => {
        	if(delay > 4000) {
            	reject('Connection Timeout :(')
            } else {
            	resolve(`Here is your fake data from ${url}`)
            }
        }, delay)
    })
}

async function makeTwoRequests() {
	let data1 = await fakeRequest('/page1');
    console.log(data1);
}

๐Ÿ‘‡ ๊ฒฐ๊ณผ๊ฐ’

โžฅ resolve, reject ๊ฒฐ๊ณผ๊ฐ€ 2๊ฐ€์ง€ ๋‚˜์˜จ๋‹ค. 

 

console.log(data1)์ด ์‹คํ–‰๋˜์ง€ ์•Š์•„์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. 

 

 

try {
	dkdidjdu.log('hi')
} catch (e) {
	console.log('its ok', e)
}

โžฅ try ๋ฌธ์— ์˜ค๋ฅ˜๊ฐ€ ๋  ์ฝ”๋“œ๋ฅผ ์ ์œผ๋ฉด, catch๋ฌธ์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ์ง€ ์ •์˜ํ•œ๋‹ค. e๋Š” ์˜ค๋ฅ˜ ๊ทธ ์ž์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. 

 

โžฅ ์—ฌ๊ธฐ์„œ๋Š” ์ฐธ์กฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. 

 


const fakeRequest = (url) => {
	return new Promise((resolve,reject) => {
    	const delay = Math.floor(Math.random() * 4500) + 500;
        setTimeout(() => {
        	if(delay > 4000) {
            	reject('Connection Timeout :(')
            } else {
            	resolve(`Here is your fake data from ${url}`)
            }
        }, delay)
    })
}

async function makeTwoRequests() {
	try {
    	let data1 = await fakeRequest('/page1');
        console.log(data1);
        let data2 = await fakeRequest('/page2');
   		console.log(data2);
	} catch (e) {
    	console.log('caught an error!')
        console.log('error is:', e)
    }
}

๐Ÿ‘‡ ๊ฒฐ๊ณผ๊ฐ’

โžฅ Promise๊ฐ€ ์–ด๋–ค ๊ฐ’์œผ๋กœ reject๋˜๋“  ๊ฐ„์— reject๋œ ์ด์œ ๋‚˜ ์ •๋ณด๊ฐ€ ๋‚˜์˜จ๋‹ค.  (์œ„ ์˜ˆ์‹œ์—์„œ๋Š” ์—ฐ๊ฒฐ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋กœ ๊ฐ€์ •ํ•จ)

catch๋ฌธ์— ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ์–ด์•ผ ์ด์œ ๋‚˜ ์ •๋ณด์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค!!

 

 

 

๐Ÿ˜ƒ ์ž˜๋ชป๋œ ๊ฐœ๋… ์ „๋‹ฌ์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์ €์˜ ์„ฑ์žฅ์— ํฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค๐Ÿค“