[TIL] Callback vs Promise vs async&await

Dev_minยท2019๋…„ 10์›” 12์ผ
3

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
17/61

๐Ÿ‘‰ CallBack

๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

๋ฌธ์ œ์  : Callback hell ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ์œ„ํ•ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์—ฐ์†ํ•ด์„œ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค. ์ฝœ๋ฐฑ์•ˆ์— ์ฝœ๋ฐฑ์„ ๊ณ„์† ๋ฌด๋Š” ํ˜•์‹์œผ๋กœ ์ด๋Ÿฌํ•œ ์ฝ”๋“œ ๊ตฌ์กฐ๋Š” ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๊ณ  ๋กœ์ง์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

ํ•ด๊ฒฐ๋ฐฉ๋ฒ• : Promise๋‚˜ Async๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

  • Callback example

    const printString = (string) => {
        setTimeout(() => {
            console.log(string)
        },
        Math.floor(Math.random() * 100) + 1
      )
    }
    
    const printAll = () => {
        printString("A")
        printString("B")
        printString("C")
    }
    printAll()
    // ๋ฌด์ž‘์œ„๋กœ ์ถœ๋ ฅ

    // callback์„ ์ด์šฉํ•œ ์ถœ๋ ฅ
    const printString = (string, callback) => {
        setTimeout(() => {
            console.log(string)
            callback()
        },
        Math.floor(Math.random() * 100) + 1
      )
    }
    
    const printAll = () => {
        printString("A", () => {
               printString("B", () => {
                      printString("C", () => {})
               })
        })
    }
    printAll()
    // A, B, C ์ˆœ์„œ๋กœ ์ถœ๋ ฅ

๐Ÿ‘‰ Promise

ํ”„๋กœ๋ฏธ์Šค๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด์ด๋‹ค.
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ž€ ? ํŠน์ • ์ฝ”๋“œ์˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์ˆ˜ํ–‰ํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํŠน์„ฑ

  • Promise์˜ 3๊ฐ€์ง€ ์ƒํƒœ
    : Promise๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์•Œ์•„์•ผ ํ•˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ฐœ๋…์ด ๋ฐ”๋กœ Promise์˜ ์ƒํƒœ์ด๋‹ค. ์ด๋Š” Promise์˜ ์ฒ˜๋ฆฌ ๊ณผ์ •์„ ์˜๋ฏธํ•œ๋‹ค. new Promise()๋กœ Promise๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ 3๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค.

    1. Pending(๋Œ€๊ธฐ) : ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋กœ์ง์ด ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์ƒํƒœ

      new Promise(function (resolve, reject) {
        // ...
      });

      : ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋Œ€๊ธฐ ์ƒํƒœ๊ฐ€ ๋˜๊ณ , ํ˜ธ์ถœํ•  ๋•Œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ resolve, reject์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

    2. Fulfilled(์ดํ–‰) : ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜์–ด Promise๊ฐ€ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์ค€ ์ƒํƒœ

      function getData() {
        return new Promise(function (resolve, reject) {
          var data = 100;
          resolve(data);
        });
      }
      
      // resolve()์˜ ๊ฒฐ๊ณผ ๊ฐ’ data๋ฅผ resolvedData๋กœ ๋ฐ›์Œ
      getData().then(function (resolvedData) {
        console.log(resolvedData); // 100
      });

      : resolve๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ดํ–‰ ์ƒํƒœ๊ฐ€ ๋œ๋‹ค. ์ดํ›„ then()์„ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

    3. Rejected(์‹คํŒจ) : ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์ƒํƒœ

      function getData() {
        return new Promise(function (resolve, reject) {
          reject(new Error("Request is failed"));
        });
      }
      
      // reject()์˜ ๊ฒฐ๊ณผ ๊ฐ’ Error๋ฅผ err์— ๋ฐ›์Œ
      getData().then().catch(function (err) {
        console.log(err); // Error: Request is failed
      });

      : reject() ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์‹คํŒจ ์ƒํƒœ๊ฐ€ ๋œ๋‹ค. ์‹คํŒจ์ƒํƒœ๊ฐ€ ๋˜๋ฉด ์‹คํŒจํ•œ ์ด์œ (์‹คํŒจ ์ฒ˜๋ฆฌ์˜ ๊ฒฐ๊ณผ ๊ฐ’)์„ catch()๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

      // example
      
      function getData() {
        return new Promise(function (resolve, reject) {
          $.get('url ์ฃผ์†Œ/products/1', function (response) {
            if (response) {
              resolve(response);
            }
            reject(new Error("Request is failed"));
          });
        });
      }
      
      // Fulfilled ๋˜๋Š” Rejected์˜ ๊ฒฐ๊ณผ ๊ฐ’ ์ถœ๋ ฅ
      getData().then(function (data) {
        console.log(data); // response ๊ฐ’ ์ถœ๋ ฅ
      }).catch(function (err) {
        console.error(err); // Error ์ถœ๋ ฅ
      });
  • Promise ํ˜•ํƒœ

    // promise ์ด์šฉ
    const printString = (string) => { 
        // callback์„ ์ธ์ž๋กœ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค
        // new Promise() ์ถ”๊ฐ€
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            console.log(string)
       		resolve()
        	},
       		 Math.floor(Math.random() * 100) + 1
      		)
        })
    }
    
    const printAll = () => {
        printString("A")
        .then(() => {
            printString("B")
        })
        .then(() => {
            printString("C")
        })
        // ๋งŒ์•ฝ reject๊ฐ€ ์‚ฌ์šฉ๋˜๋ฉด, ์ด๊ณณ์— catch๋ฅผ ์ด์šฉํ•˜์—ฌ error ํ‘œ์‹œ
    }
    printAll()
  • Promise Chaning

    function sitAndCode(){
        return new Promise((resolve, reject) => {
            setTimeout(() => { resolve('sit and code') }, 100) 
        })
    }
    function eatLunch(){
        return new Promise((resolve, reject) => {
            setTimeout(() => { resolve('eat Lunch') }, 100) 
        })
    }
    function goToBed(){
        return new Promise((resolve, reject) => {
            setTimeout(() => { resolve('go To Bed') }, 100) 
        })
    }
    
    sitAndCode()
    .then(() => {
        return eatLunch
    })
    .then(() => {
        return goToBed
    })

๐Ÿ‘‰ Async / Await

  • ๊ธฐ์กด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ธ Callback & Promise์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•˜๊ณ  ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ๊ธฐ ์ข‹์€ ์ฝ”๋“œ๋กœ ์ž‘์„ฑ ๊ฐ€๋Šฅ

    // ๊ธฐ๋ณธ ๋ฌธ๋ฒ•
    async function ํ•จ์ˆ˜๋ช…() {
      await ๋น„๋™๊ธฐ_์ฒ˜๋ฆฌ_๋ฉ”์„œ๋“œ_๋ช…();
    }

    : ํ•จ์ˆ˜ ์•ž์— async ๋ผ๋Š” ์˜ˆ์•ฝ์–ด๋ฅผ ๋ถ™์ธ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•จ์ˆ˜ ๋‚ด๋ถ€ ๋กœ์ง ์ค‘ HTTP ํ†ต์‹ ์„ ํ•˜๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ฝ”๋“œ ์•ž์— await๋ฅผ ๋ถ™์ธ๋‹ค.

    ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฒƒ์€ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ๊ฐ€ ๊ผญ Promise ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ await๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค
    ์ผ๋ฐ˜์ ์œผ๋กœ await์˜ ๋Œ€์ƒ์ด ๋˜๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ฝ”๋“œ๋Š” Axios ๋“ฑ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” API ํ˜ธ์ถœ ํ•จ์ˆ˜

    function sitAndCode(){
        return new Promise((resolve, reject) => {
            setTimeout(() => { resolve('sit and code') }, 100) 
        })
    }
    function eatLunch(){
        return new Promise((resolve, reject) => {
            setTimeout(() => { resolve('eat Lunch') }, 100) 
        })
    }
    function goToBed(){
        return new Promise((resolve, reject) => {
            setTimeout(() => { resolve('go To Bed') }, 100) 
        })
    }
    
    var result = async () => {
        const one = await sitAndCode();
        console.log(one);
        const two = await eatLunch();
        console.log(two);
        const three = await goToBed();
        console.log(three);
    }
    result();

  • ์˜ˆ์™ธ์ฒ˜๋ฆฌ
    : try catch ๋ฐฉ๋ฒ•

    async function logTodoTitle() {
      try {
        var user = await fetchUser();
        if (user.id === 1) {
          var todo = await fetchTodo();
          console.log(todo.title); // delectus aut autem
        }
      } catch (error) {
        console.log(error);
      }
    }
profile
TIL record

0๊ฐœ์˜ ๋Œ“๊ธ€