๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • What would life be If we had no courage to attemp anything?
Language/JavaScript

JavaScript - Asynchronous JavaScript(์ฝœ๋ฐฑํ•จ์ˆ˜, Async callbacks,Promise), Axios

by DevIseo 2022. 5. 3.

*๏ธโƒฃ Callback Function - ์ธ์ž๋กœ ๋„˜๊ธฐ๋Š” ํ•จ์ˆ˜

  • ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์ธ์ž๋กœ ์ „๋‹ฌ๋œ ํ•จ์ˆ˜
  • ์™ธ๋ถ€ ํ•จ์ˆ˜ ๋‚ด์—์„œ ํ˜ธ์ถœ๋˜์–ด ์ผ์ข…์˜ ๋ฃจํ‹ด ๋˜๋Š” ์ž‘์—…์„ ์™„๋ฃŒํ•จ
  • ๋™๊ธฐ์‹, ๋น„๋™๊ธฐ์‹ ๋ชจ๋‘ ์‚ฌ์šฉ๋จ
    • ๊ทธ๋Ÿฌ๋‚˜ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„ ์ฝ”๋“œ ์‹คํ–‰์„ ๊ณ„์†ํ•˜๋Š” ๋ฐ ์ฃผ๋กœ ์‚ฌ์šฉ๋จ
  • ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„ ์ฝ”๋“œ ์‹คํ–‰์„ ๊ณ„์†ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋น„๋™๊ธฐ ์ฝœ๋ฐฑ(asynchronous callback)์ด๋ผ๊ณ  ํ•จ

|JavaScript์˜ ํ•จ์ˆ˜ === โ€œ์ผ๊ธ‰ ๊ฐ์ฒด(First Class Object)โ€

  • ์ผ๊ธ‰ ๊ฐ์ฒด (์ผ๊ธ‰ ํ•จ์ˆ˜)
    • ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—ฐ์‚ฐ์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋Š” ๊ฐ์ฒด(ํ•จ์ˆ˜)
  • ์ผ๊ธ‰ ๊ฐ์ฒด์˜ ์กฐ๊ฑด
    • ์ธ์ž๋กœ ๋„˜๊ธธ ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
    • ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
    • ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ

|Async callbacks

ํ•จ์ˆ˜ โ‡’ ํ˜ธ์ถœ์„ ํ•ด์•ผ ์˜๋ฏธ๋ฅผ ๊ฐ–๊ฒŒ ๋จ!

  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ฝ”๋“œ ์‹คํ–‰์„ ์‹œ์ž‘ํ•  ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ธ์ž๋กœ ์ง€์ •๋œ ํ•จ์ˆ˜
  • ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ฝ”๋“œ ์‹คํ–‰์ด ๋๋‚˜๋ฉด callback ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ์Œ์„ ์•Œ๋ฆฌ๊ฑฐ๋‚˜, ๋‹ค์Œ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Œ
    • ์‚ฌ์šฉ ์˜ˆ์‹œ) addEventListener()์˜ ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜
  • callback ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•  ๋•Œ, ํ•จ์ˆ˜์˜ ์ฐธ์กฐ๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•  ๋ฟ์ด์ง€ ์ฆ‰์‹œ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ , ํ•จ์ˆ˜์˜ body์—์„œ โ€œcalled backโ€๋จ. ์ •์˜๋œ ํ•จ์ˆ˜๋Š” ๋•Œ๊ฐ€ ๋˜๋ฉด callback ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• ์„ ํ•จ

|Why use callback ?

  • callback ํ•จ์ˆ˜๋Š” ๋ช…์‹œ์ ์ธ ํ˜ธ์ถœ์ด ์•„๋‹Œ ํŠน์ • ๋ฃจํ‹ด ํ˜น์€ action์— ์˜ํ•ด ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜
  • Django ์˜ ๊ฒฝ์šฐ โ€œ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉดโ€, event์˜ ๊ฒฝ์šฐ โ€œํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉดโ€์ด๋ผ๋Š” ์กฐ๊ฑด์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฑด โ€˜Callback functionโ€™ ๊ฐœ๋… ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅ
  • ๋น„๋™๊ธฐ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•  ๋•Œ callback ํ•จ์ˆ˜๋Š” ํ•„์ˆ˜
    • ๋ช…์‹œ์ ์ธ ํ˜ธ์ถœ์ด ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜์—ฌ ํ•ด๋‹น ํ•จ์ˆ˜ ๋‚ด์—์„œ ํŠน์ • ์‹œ์ 

|callback Hell

  • ์ˆœ์ฐจ์ ์ธ ์—ฐ์‡„ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด โ€œcallback ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ๊ทธ ๋‹ค์Œ callback ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ๋˜ ๊ทธ ํ•จ์ˆ˜์˜ callback ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ ...โ€์˜ ํŒจํ„ด์ด ์ง€์†์ ์œผ๋กœ ๋ฐ˜๋ณต๋จ
  • ์ฆ‰, ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์—ฐ์‡„ ๋น„๋™๊ธฐ ์ž‘์—…์„ ํ•  ๋•Œ ๋งˆ์ฃผํ•˜๋Š” ์ƒํ™ฉ
  • ์ด๋ฅผ callback Hell(์ฝœ๋ฐฑ ์ง€์˜ฅ) ํ˜น์€ pyramid of doom(ํŒŒ๋ฉธ์˜ ํ”ผ๋ผ๋ฏธ๋“œ)์ด๋ผ ํ•จ
  • ์œ„์™€ ๊ฐ™์€ ์ƒํ™ฉ์ด ๋ฒŒ์–ด์งˆ ๊ฒฝ์šฐ ์•„๋ž˜ ์‚ฌํ•ญ๋“ค์„ ํ†ต์ œํ•˜๊ธฐ ์–ด๋ ค์›€
    • ๋””๋ฒ„๊น…
    • ์ฝ”๋“œ ๊ฐ€๋…์„ฑ

|How to solve callback Hell?

  1. Keep your code shallow (์ฝ”๋“œ์˜ ๊นŠ์ด๋ฅผ ์–•๊ฒŒ ์œ ์ง€)
  2. Modularize (๋ชจ๋“ˆํ™”)
  3. Handle every single error (๋ชจ๋“  ๋‹จ์ผ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ)
  4. Promise callbacks (Promise ์ฝœ๋ฐฑ ๋ฐฉ์‹ ์‚ฌ์šฉ)

*๏ธโƒฃPromise

|Promise object - ๋‹ค์งํ•˜๋Š” ๋Š๋‚Œ

const myPromise = axios.get(URL)
//console.log(myPromise) // Promise Object

myPromise
	.then(response => {
		return response.data
})
//chaining
axios.get(URL)
	.then(response => {
		return response.data
})
	.then(response => {
		return response.title
})
	.catch(error => {
		console.log(error)
})
	.finally(function(){
		console.log('๋‚˜๋Š” ๋งˆ์ง€๋ง‰์— ๋ฌด์กฐ๊ฑด ์‹œํ–‰!!')
})
  • ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ตœ์ข… ์™„๋ฃŒ ๋˜๋Š” ์‹คํŒจ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด
    • ๋ฏธ๋ž˜์˜ ์™„๋ฃŒ ๋˜๋Š” ์‹คํŒจ์™€ ๊ทธ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋‚˜ํƒ€๋ƒ„
    • ๋ฏธ๋ž˜์˜ ์–ด๋–ค ์ƒํ™ฉ์— ๋Œ€ํ•œ ์•ฝ์†
  • **์„ฑ๊ณต(์ดํ–‰)**์— ๋Œ€ํ•œ ์•ฝ์†
    • .then()
  • **์‹คํŒจ(๊ฑฐ์ ˆ)**์— ๋Œ€ํ•œ ์•ฝ์†
    • .catch()

|Promise methods

.then(callback)

  • ์ด์ „ ์ž‘์—…(promise)์ด ์„ฑ๊ณตํ–ˆ์„ ๋•Œ(์ดํ–‰ํ–ˆ์„ ๋•Œ) ์ˆ˜ํ–‰ํ•  ์ž‘์—…์„ ๋‚˜ํƒ€๋‚ด๋Š” callback ํ•จ์ˆ˜
  • ๊ทธ๋ฆฌ๊ณ  ๊ฐ callback ํ•จ์ˆ˜๋Š” ์ด์ „ ์ž‘์—…์˜ ์„ฑ๊ณต ๊ฒฐ๊ณผ๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ ๋ฐ›์Œ
  • ๋”ฐ๋ผ์„œ ์„ฑ๊ณตํ–ˆ์„ ๋•Œ์˜ ์ฝ”๋“œ๋ฅผ callback ํ•จ์ˆ˜ ์•ˆ์— ์ž‘์„ฑ

.catch(callback)

  • .then์ด ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•˜๋ฉด(๊ฑฐ๋ถ€ ๋˜๋ฉด) ๋™์ž‘ (๋™๊ธฐ์‹์˜ โ€˜try - exceptโ€™ ๊ตฌ๋ฌธ๊ณผ ์œ ์‚ฌ)
  • ์ด์ „ ์ž‘์—…์˜ ์‹คํŒจ๋กœ ์ธํ•ด ์ƒ์„ฑ๋œ error ๊ฐ์ฒด๋Š” catch ๋ธ”๋ก ์•ˆ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

๊ฐ๊ฐ์˜ .then() ๋ธ”๋ก์€ ์„œ๋กœ ๋‹ค๋ฅธ promise๋ฅผ ๋ฐ˜ํ™˜

  • ์ฆ‰, .then()์„ ์—ฌ๋Ÿฌ ๊ฐœ ์‚ฌ์šฉ(chaining)ํ•˜์—ฌ ์—ฐ์‡„์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ
  • ๊ฒฐ๊ตญ ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฐจ๋ก€๋Œ€๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป

.then()๊ณผ .catch() ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋‘ promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— chaining ๊ฐ€๋Šฅ

์ฃผ์˜

  • ๋ฐ˜ํ™˜ ๊ฐ’์ด ๋ฐ˜๋“œ์‹œ ์žˆ์–ด์•ผ ํ•จ
  • ์—†๋‹ค๋ฉด callback ํ•จ์ˆ˜๊ฐ€ ์ด์ „์˜ promise ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์—†์Œ

.finally(callback)

  • Promise ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜
  • ๊ฒฐ๊ณผ์™€ ์ƒ๊ด€์—†์ด ๋ฌด์กฐ๊ฑด ์ง€์ •๋œ callback ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰
  • ์–ด๋– ํ•œ ์ธ์ž๋„ ์ „๋‹ฌ๋ฐ›์ง€ ์•Š์Œ
    • Promise๊ฐ€ ์„ฑ๊ณต๋˜์—ˆ๋Š”์ง€ ๊ฑฐ์ ˆ๋˜์—ˆ๋Š”์ง€ ํŒ๋‹จํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ
  • ๋ฌด์กฐ๊ฑด ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์ ˆ์—์„œ ํ™œ์šฉ
    • .then()๊ณผ .catch() ๋ธ”๋ก์—์„œ์˜ ์ฝ”๋“œ ์ค‘๋ณต์„ ๋ฐฉ์ง€
//callback Hell์ฝ”๋“œ

work1(function(result1){
	work2(result1,fucntion(result2){
		work3(result2,function(result3){
			console.log('์ตœ์ข… ๊ฒฐ๊ณผ:'+ result3)
		})
	})
})

//Promise์ฝ”๋“œ(Promise Chaining)
work1().then(function(result1){
	return work2(result1)
})
.then(function(result2){
	return work3(result2)
})
.then(function(result3){
	console.log('์ตœ์ข…๊ฒฐ๊ณผ: '+result3)
})
.catch(failureCallback)

|Promise๊ฐ€ ๋ณด์žฅํ•˜๋Š” ๊ฒƒ

  • Async callback ์ž‘์„ฑ ์Šคํƒ€์ผ๊ณผ ๋‹ฌ๋ฆฌ Promise๊ฐ€ ๋ณด์žฅํ•˜๋Š” ํŠน์ง•
  1. callback ํ•จ์ˆ˜๋Š” JavaScript์˜ Event Loop๊ฐ€ ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ Call Stack์„ ์™„๋ฃŒํ•˜๊ธฐ ์ด์ „์—๋Š” ์ ˆ๋Œ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์Œ โ†’๋น„๋™๊ธฐ์  ํŠน์„ฑ ๋•Œ๋ฌธ!
    • Promise callback ํ•จ์ˆ˜๋Š” Event Queue์— ๋ฐฐ์น˜๋˜๋Š” ์—„๊ฒฉํ•œ ์ˆœ์„œ๋กœ ํ˜ธ์ถœ๋จ
  2. ๋น„๋™๊ธฐ ์ž‘์—…์ด ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์‹คํŒจํ•œ ๋’ค์— .then() ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ถ”๊ฐ€ํ•œ ๊ฒฝ์šฐ์—๋„ 1๋ฒˆ๊ณผ ๋˜‘๊ฐ™ ์ด ๋™์ž‘
  3. .then()์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ callback ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Œ (Chaining)
    • ๊ฐ๊ฐ์˜ callback์€ ์ฃผ์–ด์ง„ ์ˆœ์„œ๋Œ€๋กœ ํ•˜๋‚˜ํ•˜๋‚˜ ์‹คํ–‰ํ•˜๊ฒŒ ๋จ
    • Chaining์€ Promise์˜ ๊ฐ€์žฅ ๋›ฐ์–ด๋‚œ ์žฅ์ 

*๏ธโƒฃAxios

  • ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์œ„ํ•œ Promise ๊ธฐ๋ฐ˜์˜ ํด๋ผ์ด์–ธํŠธ
  • ์›๋ž˜๋Š” โ€œXHRโ€์ด๋ผ๋Š” ๋ธŒ๋ผ์šฐ์ € ๋‚ด์žฅ ๊ฐ์ฒด๋ฅผ ํ™œ์šฉํ•ด AJAX ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ, ์ด๋ณด๋‹ค ํŽธ๋ฆฌํ•œ AJAX ์š”์ฒญ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋„์›€์„ ์คŒ
    • ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ์ธํ„ฐํŽ˜์ด์Šค์™€ ํ•จ๊ป˜ ํŒจํ‚ค์ง€๋กœ ์‚ฌ์šฉ์ด ๊ฐ„ํŽธํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ œ๊ณต
axios.get('<https://jsonplaceholder.typicode.com/todos/1>') //Promise return
	.then(..)
	.catch(..)

//Axios ์‚ฌ์šฉํ•˜๊ธฐ
  
  
  
    const URL = '<<a href=https://jsonplaceholder.typicode.com/todos/1>https://jsonplaceholder.typicode.com/todos/1</a>>'
    
    async function test(){
      const response = await axios.get(URL)
      const data = response.data
      console.log(data.title)
    }

    test().catch(err=>console.log(err))
  

//Axios ์˜ˆ์‹œ
const URL = '<https://jsonplaceholder.typicode.com/todos/1>'

axios.get(URL)
	.then(function(response){
		console.log(response)
		return response.data
	})
	.then(function(data){
		return data.title
	})
	.then(function(title){
		console.log(title)
	})
	.catch(function(error){
		console.log(error)
	})
	.finally(function(){
		console.log('์ด๊ฑด ๋ฌด์กฐ๊ฑด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.')
	})

*๏ธโƒฃasync & await

|async & await

<์‚ฌ์šฉ๋ฒ•>

async - ์‚ฌ์šฉํ•  ํ•จ์ˆ˜ ์•ž์— ๋ถ™์—ฌ์ค€๋‹ค.

await - async ํ•จ์ˆ˜ ์‚ฌ์šฉ ์‹œ axios์•ž์— ๋ถ™์ธ๋‹ค

  • ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•
    • ECMAScript 2017(ES8)์—์„œ ๋“ฑ์žฅ
  • ๊ธฐ์กด Promise ์‹œ์Šคํ…œ ์œ„์— ๊ตฌ์ถ•๋œ syntactic sugar
    • Promise ๊ตฌ์กฐ์˜ then chaining์„ ์ œ๊ฑฐ
    • ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์กฐ๊ธˆ ๋” ๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ํ‘œํ˜„
    • Syntactic sugar
      • ๋” ์‰ฝ๊ฒŒ ์ฝ๊ณ  ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ๋‚ด์˜ ๊ตฌ๋ฌธ
      • ์ฆ‰, ๋ฌธ๋ฒ•์  ๊ธฐ๋Šฅ์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋˜ ์‚ฌ์šฉ์ž๊ฐ€ ์ง๊ด€์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ฆ
//Promise ์ฝ”๋“œ
const URL = '<https://dog.ceo/api>'
function fetchFirstDogImage() {
axios.get(URL + '/breeds/list/all')
.then(res => {
const breed = Object.keys(res.data.message)[0]
return axios.get(URL + `/breed/${breed}/images`)
})
.then(res => {
console.log(res)
})
.catch(err => {
console.error(err.response)
})
}
fetchFirstDogImage()

//async & await ์ฝ”๋“œ
const URL = '<https://dog.ceo/api>'
async function fetchFirstDogImage() {
const res = await axios.get(URL + '/breeds/list/all')
const breed = Object.keys(res.data.message)[0]
const images = await axios.get(URL + `/breed/${breed}/images`)
console.log(images)
}
fetchFirstDogImage()
.catch(err => console.error(err.response)

'Language > JavaScript' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

JavaScript - Event  (0) 2022.05.03
JavaScript - DOM(Document Object Model)  (0) 2022.05.03
JavaScript - AJAX, Asynchronous (๋น„๋™๊ธฐ)  (0) 2022.05.03
JavaScript - ํ”„๋กœํ† ํƒ€์ž…(prototype), ํด๋ž˜์Šค(class)  (0) 2022.05.03
JavaScript - this  (0) 2022.05.02

๋Œ“๊ธ€