[JS] 비동기 Promise, Async-await

Song·2021년 11월 23일
0

bootcamp

목록 보기
6/11

자바스크립트는 비동기를 실행하는 특징을 가지기 때문에 다른 언어에 비해 비동기 처리가 훨씬 수월하다.

Promise

시작과 끝이 명확하지 않기 때문에, 작업 상태를 저장할 클래스를 새로 만들어 담아둔다. 변수를 따로 만들어 이름을 붙이고 만들기 때문에 상태관리에 더 용이하다.

callback으로 작성하면 상태를 명확하게 확인하기 어렵다(return되는 값이 따로 없다 - 함수만 호출함). 따라서 Promise로 추상화하여 간편하게 작성한다.

Promise의 상태 3가지

  • pending
  • fufilled
  • rejected

Promise의 인자에는 'Promise 실행함수'가 온다. 실행함수 안의 첫번째 인자는 resolve함수와 reject함수가 들어간다.

const newPromise = new Promise( //promise 실행함수
  (resolve,reject) => { 
    //어떤 행동을 했을때(fulfilled) -> resolve('성공한 결과값');
    //어떤 행동을 했을 때(rejected) -> reject('실패시 에러객체');
    //아무것도 안하거나 아직 resolve가 호출되지 않은 경우 -> pending 상태
  }
 )

서비스를 잘 제공하기 위해서는 성공했을 때와 실패했을 때 모두를 컨트롤할 수 있어야 한다. 성공과 실패에 따라 해결방법이 달라야 하기 때문에 로직을 분리되어야 한다.

Promise를 사용하기 위해서는 .then을 사용해야 해당 promise값을 사용 가능하다.

const theOtherPromise = newPromise.then(); 
//이렇게 써도 theOtherPromise에는 Promise가 전달된다.
console.log(theOtherPromise + '!') 
//변수로 따로 담았다고 하더라도 내가 원하는 promise안의 값을 사용할 수 없다.

promise.then()을 사용할 경우 원하는 연산을 할 수 있다.

const anotherPromise = newPromise.then((result)=>{	
  //.then()을 사용해야 그 값을 온전히 전달받아 사용할 수 있다
  console.log(result + '!');
  return result+'!'; 
  //promise안의 resolve시 값을 그대로 사용하고 싶으면 return문을 이용해
  //.then()문 안에서 원하는 작업을 실행하여 return 해준다.
	})

하지만 Promise 바깥에 어떤 변수를 만들고 이를 return하고자 한다면 크게 문제는 없을지라도 promise를 쓰는 장점을 살릴 수 없다. 상태 변화에 따라 값이 변하고 다르게 처리하기 위해서 promise를 쓰는데 아래의 코드와 같이 쓸 경우 상태가 반영되지 않는다. callback함수와 크게 다르지 않아 promise.then()이 가져다주는 상태를 반영해주지 않는다.

let temp;
const anotherPromise = newPromise.then((result)=>{	
  //.then()을 사용해야 그 값을 온전히 전달받아 사용할 수 있다
  console.log(result + '!');
  temp = result+'!'; 
  //이렇게 사용할 경우 callback과 다를바가 없어진다
	})

3번 실습문제(basicChaining) - 동기적으로 작용하게끔 만든다. 작업을 끝내야 그 다음 .then()으로 넘어가기 때문에.

만약 arr를 따로 선언해 그 안에 결과값을 담아 return한다면?

let arr = [];
return somePromise(user1path)
.then((user1text)=>{
  //...
  	})
.then((user2text)=>{
  arr.push(user1);
  arr.push(user2);
  return arr;
	})

이렇게 arr를 따로 선언해 arr.push를 쓰면 안되는 이유
: arr.push를 쓰면 상태와 상관 없이 무조건 user1과 user2를 arr.push해버린다. 데이터가 적을 때는 순서대로 넣겠지만 그렇지 않을 경우에는 장담할 수 없다. 즉 promise를 사용해 비동기로 사용하게되면 순서가 섞여서 들어올수도 있어서 안정적인가?에 대해서는 장담을 못한다(side effect 주의)
.then()을 사용해 첫번째 user1 작업이 실행되고 user2 작업이 실행되도록 상태를 순서대로 조절한다.
returnpromise로 돌려주는 이유도 해당 promise를 해결하고 난 다음에 작업을 실행하도록 안정적으로 운영하기 위해서이다.

4번 실습문제(promise.all) - 비동기적으로 작동/ 반복처리는 반복문 사용
처리해야할 연산이 많을 경우에는 비동기적으로 작동하여 처리하는게 속도가 더 빠르다.
배열로 .then()에 넘겨준다면 map() 함수로 처리해줄 수 있다.


5번 실습문제(async-await)

async-await은 비동기로 처리되는 자바스크립트에서 동기적으로 작동하게끔 만든다.

resolve를 다 해서 작업을 받아오기 때문에 동기적으로 사용하는 것과 비슷하다. await을 쓰는건 일부로 동기적인 작업을 하기 위함이다. 따라서 남용해서 작성하지 않도록 동기적 작업이 필요한 경우에만 사용한다. 비동기적으로 사용할 때는 순서가 지켜지지 않고 작업이 이루어지기 때문에 순서를 지켜서 작업을 해야할 때만 이를 사용하도록 한다.

await를 쓰지 않은 문장의 경우에는 await 작업이 다 끝날 때까지 기다리지 않고 비동기적으로 실행이 되기 때문에 실행되는 순서를 조정하기 위해서는 await를 사용해 동기적으로 조절해줘야 한다.

Promise.all

멀티스레드와 같은 작동을 하는 Promise.all은 작업을 더 빠르게 만든다.
promise들의 반복문으로 반복적으로 써야할 작업을 한번에 처리가능하게 한다.

0개의 댓글