async await

윤수호·2022년 6월 10일
0

일단 async await를 설명하기에 앞서

비동기 동기에 대해 알아보고 콜백함수를 알아본 후 promise에 대해 알아본 후
async await에 대해 알아보는게 좋을 것 같습니다.

1.비동기 동기

동기처리란
한번에 한줄씩 처리된다는 뜻입니다.
한마디로

<script>
  console.log(1); 
  console.log(2); 
  console.log(3);
</script>

이러한 코드 처럼 순차적으로 처리되는것을 동기처리된다고 합니다.
그리고 이와 반대되는 비동기 처리는

console.log(1);
setTimeout(function(){
  console.log(2);
}, 1000);
console.log(3);

이런 코드가 있습니다.
위 코드는 1,3,2순으로 console.log에 찍힐 것입니다.
왜냐하면 setTimeout함수로 console.log(2)를 1초 후에 실행하게 하였으니까요.
이러한 작동을 비동기처리라고 합니다.

근데 비동기처리를 쓰고 싶지만
함수는 순차적으로 사용하고 싶을 수도 있지 않나요?
그럴때 보통 콜백함수를 사용합니다.
자바스크립트는 비동기상황 등에서 코드를 순차적으로 실행하고 싶을 때 콜백함수를 적극 활용합니다.

콜백함수

콜백함수를 한문장으로 요약하라고하면 저는 코드를 순차적으로 실행하고 싶을 때 사용하는
함수 디자인이라고 설명할 것 같습니다.
또는 함수안에 들어가는 함수라고 설명 할 것같습니다.
예를 들면 순차적으로 실행하고 싶은 함수가 두개 있다고 한다면
어떻게 코드짜면 될까요?

function 첫째함수(콜백){
  console.log(1);
  콜백();
}

function 둘째함수(){
  console.log(2)
}

첫째함수(둘째함수);

콜백함수로 짤 경우 위와같은 코드로 짤 수 있습니다.
보면 파라미터 자리에 함수가 들어가 있고, 첫째 함수안에는 콜백이라는 이름으로 둘째함수를 받아서 내부에서 실행시키고 있습니다.

이러한 함수 디자인으로 되어 있는걸 콜백함수라고 합니다.

그리고 보통 위와같이 둘째함수는 이름을 따로 만들지않고 바로 function을 넣어서 사용합니다.

function 첫째함수(콜백){
  console.log(1);
  콜백();
}


첫째함수(function(){
console.log(2)
});

이름을 넣고 싶다면

function 첫째함수(콜백){
  console.log(1);
  콜백();
}


첫째함수(function 둘째함수(){
console.log(2)
});

이렇게 넣을 수는 있지만 이름을 안짓는 이유가 재활용을 안할것 같기때문인데

윗코드는 이름을 넣어도 재사용이 힘들기때문에 보통 이름없이 사용합니다.

그런데 이러한 방식으로 짓게 된다면

첫째함수(function(){
  둘째함수(function(){
    셋째함수(function(){
      어쩌구..
    });
  });
}):

봤을때 너무 복작해보이고 코드가 너무 지저분해 보입니다.

때문에 이러한 점을 해결하기 위해 promise라는 디자인 패턴이 생겼습니다.

promise

프로미스의 사용방법은 생각보다 간단합니다.
아래와 같이 사용하면 promise사용법은 끝입니다.

var 프로미스 = new Promise();

프로미스.then(function(){

}).catch(function(){

});

프로미스 안의 코드가 실행이 완료가 되었을 때 then() 함수 내의 코드를 실행시켜줍니다.

코드가 실행이 실패했을 경우엔 catch() 함수 내의 코드를 실행시켜줍니다.

(지금은 프로미스 안에 코드가 암것도 없지만요)

Promise가 콜백함수보다 좋다고 하는 이유는 두개가 있습니다.

  1. 콜백함수와는 다르게 순차적으로 뭔가를 실행할 때 코드가 옆으로 길어지지 않습니다. then 함수를 붙여서 순차적으로 실행하니까요.
  2. 콜백함수는 불가능한 '실패시 특정 코드를 실행해주세요~' 라고 코드를 짤 수 있습니다. (catch)

그럼 promise가 실패,성공을 판단짓는 방법을 알려드리겠습니다.

Promise()안에 콜백함수를 하나 추가해주시면 그 안에서 성공/실패 판정을 내릴 수 있습니다.

성공()이라고 첫째 파라미터를 함수형태로 작성하면 성공판정이 됩니다.

실패()라고 둘째 파라미터를 함수형태로 작성하면 실패판정이 됩니다.

var 프로미스 = new Promise(function(성공, 실패){
  var 어려운연산 = 1 + 1;
  성공();
});

프로미스.then(function(){
  console.log('연산이 성공했습니다')
}).catch(function(){

});

Promise()안에 어려운 수학 연산을 해주는 기능을 추가했습니다.

그리고 그 연산이 완료되면 성공() 코드를 실행하도록 코드를 추가했습니다.

(일반 코드들은 저렇게 위아래로 나란히 적으면 그냥 차례로 실행됩니다)

  1. 이제 프로미스 내의 1+1 이라는 어려운 수학연산이 완료되면 성공() 판정을 내리며,

  2. 성공시 then() 내의 코드를 실행해줍니다.

var 프로미스 = new Promise(function(성공, 실패){
  var 어려운연산 = 1 + 1;
  실패();
});

프로미스.then(function(){
  console.log('연산이 성공했습니다')
}).catch(function(){
  console.log('실패했습니다')
});

실패()라는 함수를 실행하는 순간 실패판정을 내립니다.

그렇게 되면 catch() 내의 코드를 실행해줍니다.

실패의 경우 다른 내용을 실행해줄 수도 있고하니 그냥 콜백함수 디자인보다 훨씬 뭔가 직관적이고 유용합니다.

참고로 연산결과를 then 안에서 활용하고 싶으면

성공(); 함수 구멍안에 넣어주시면 됩니다.

var 프로미스 = new Promise(function(성공, 실패){
  var 어려운연산 = 1 + 1;
  성공(어려운연산);
});

프로미스.then(function(결과){
  console.log('연산이 성공했습니다' + 결과)
}).catch(function(){
  console.log('실패했습니다')
});

Promise의 몇가지 특징

  1. 일단 new Promise()로 생성된 변수를 콘솔창에 출력해보시면 현재 상태를 알 수 있습니다.

성공/실패 판정 전에는 이라고 나오며

성공 후엔

실패 후엔 이런 식으로 나옵니다.

이렇게 프로미스 오브젝트들은 3개 상태가 있습니다.

그리고 성공을 실패나 대기상태로 다시 되돌릴 순 없습니다. 참고로 알아둡시다.

  1. Promise는 동기를 비동기로 만들어주는 코드가 아닙니다.

Promise는 비동기적 실행과 전혀 상관이 없습니다.

그냥 코딩을 예쁘게 할 수 있는 일종의 디자인 패턴입니다.

예를 들면.. Promise 안에 10초 걸리는 어려운 연산을 시키면 10초동안 브라우저가 멈춥니다.

10초 걸리는 연산을 해결될 때 까지 대기실에 제껴두고 그런거 아닙니다.

(그냥 원래 자바스크립트는 평상시엔 동기적으로 실행이 되며 비동기 실행을 지원하는 특수한 함수들 덕분에 가끔 비동기적 실행이 될 뿐입니다.)

Promise가 어렵다면 그보다 훨씬 쉽게 쓸 수 있는 ES8 문법이 있습니다.

async, await이라는 키워드인데 각각 Promise와 then을 매우 쉽게 만들어주는 문법입니다.

같이 알아봅시다.

async, await

async 키워드를 쓰면 Promise 오브젝트가 절로 생성됩니다.

말그대로 new Promise() 이런식으로 사용하실 필요가 없습니다.

하지만 이 키워드는 function 선언 앞에만 붙일 수 있습니다.

그럼 이 함수 자체가 Promise가 되어버립니다.

그래서 이 함수를 실행할 때 뒤에 then을 붙일 수 있습니다. Promise니까요.

(함수를 실행하면 그 자리에 Promise 인스턴스 (new Promise() 로 만든 오브젝트)가 남습니다. )

async function 더하기(){
1 + 1 
}

더하기().then(function(){
console.log('더하기 성공했어요')
});

그럼 이와 같이 then도 똑같이 사용할 수 있습니다.
하지만 저희는 then보다도 await이라는 함수가 있기때문에 await함수를 사용하겠습니다.

async function 더하기(){
var 어려운연산 = new Promise((성공, 실패)=>{
  var 결과 = 1 + 1;
  성공();
});
var 결과 = await 어려운연산;
}
더하기();

어려운연산.then() 과 매우 유사한 문법입니다.

정확한 뜻은 어려운연산 Promise를 기다린 다음에 완료되면 결과를 변수에 담아주세요

입니다.

연산 결과를 출력하거나 그러고 싶다면

성공 함수에 파라미터를 담아주시면 됩니다.

async function 더하기(){
var 어려운연산 = new Promise((성공, 실패)=>{
  var 결과 = 1 + 1;
  성공(결과);
});
var 결과 = await 어려운연산;
console.log(결과);//2
}
더하기();
profile
기술블로그 시작

0개의 댓글