비동기 callback / promise 알아보기

코공·2020년 12월 22일
0
post-thumbnail

주의. 자바스크립트에 대해 잘 알지 못하는 사람이 공부하려고 작성한 글이기 때문입니다. 내용이 부실하거나 잘못된 정보가 있을 수 있음. 내가 뭘 알아?

비동기 vs 동기

동기 : 주어진 일들을 순차적으로(직렬적으로) 수행하는 방식.

동기는 한 번에 하나의 업무만 할 수 있다. 한 업무가 끝나기 전까지 다른 업무는 중단된다.

만약 은행에 갔는데 직원이 1명이다. 그러면 번호표를 뽑은 우리는 앞 사람이 끝나기 전까지 은행 일을 볼 수가 없다. 매우 슬프지 않은가?

흔히 쓰는 코드는 대부분 동기로 일을 처리한다.

function func1 () {
console.log("1번")
}

function func2 () {
console.log("2번")
}

function func3(){
console.log("3번")
}

function func4(){
func1()
func2() 
func3()
}

func4() 
// 1번 
// 2번
// 3번

func4()에 있는 아이들은 1번이 끝나야 2번, 2번이 끝나야 3번의 console.log를 가져오게 된다. func1000이 있다면 이 추운. 싸늘하게 발견될 수도 있다.

아마 이렇게 초등학교 때 계주를 달리던 것 처럼.. 애타게 내 뒷 사람을 기다리는 것처럼.. func2는 그렇게 func1을 기다린다.. 그런데 당신은 느려서 계주한 기억이 없기에 공감을 못할 수도 있다.. ^__^..


비동기 : 주어진 일들을 동시에(병렬적으로) 수행하는 방식.

비동기는 동기와 다르다. 수행하던 일이 끝나지 않아도 다른 일을 시작할 수 있다.

자바스크립트의 대부분의 DOM 이벤트나 Timer 함수(setTimeout, setInterval)와 같은 것들이 비동기적으로 일을 하게 된다.

비동기로 일을 하게 되면 당신은 앞 사람을 기다리지 않아도 된다.
비동기의 대표적인 함수 setTimeout으로 위의 코드를 수정해봤다.

function func1 (string) {
    setTimeout(
      () => {
        console.log(string)
    },
    Math.floor(Math.random() * 100) +1
  )
}

function func2 () {
func1("1번")
func1("2번")
func1("3번")
}

// 항상 다름 1번 or 2번 or 3번
// 항상 다름 1번 or 2번 or 3번
// 항상 다름 1번 or 2번 or 3번

// 

위에 코드는 func1,2,3이 동시에 일을 시작한다.
그리고 시간 초는 랜덤으로 설정해서 항상 다른 결과가 나온다.

이렇게. 동기랑은 다르게 함수가 실핸된다.

이러면 당신은 움직이면서 스킬을 쓸 수 있다.

그런데 위처럼 코드를 실행하면 항상 랜덤 순서로 일의 결과가 나온다.
나는 1,2,3으로 나오게 하고 싶은데...

그래서 비동기함수들을 순차적으로 결과가 나오게 조절해주는 함수들이 있다.
바로 callback / promise / async,Await 이다.

하나씩 알아보자.


Callback

우리는 callback을 이용해서 비동기함수를 조절할 수 있다.
위의 코드에 인자로 callback을 넣어주자.

function func1 (string, callback) {
    setTimeout(
      () => {
        console.log(string)
        callback()
    },
    Math.floor(Math.random() * 100) +1
  )
}

function func2 (){
 func1("1번", () => {
    func1("2번", () => {
        func1("3번", () => {})
     })
  })
}

}

콜백을 이용하기 전에는 각자 시간에 따라 결과값이 랜덤으로 나왔다.
그러나 콜백을 이용하면 요 비동기를 조절하여 내가 원했던 1,2,3번으로 결과값이 나오도록 조정할 수 있다!

Promise

promise도 callback처럼 비동기를 조절할 수 있다. callback보다 더 유용함.
자세히 알아보자.

promise 예제

위에 있는 코드를 callback 대신 promise로 작성해 보았다.

function func1 (string) {
    return new Promise((resolve, reject) =>{ // 추가된 부분
    setTimeout(
      () => {
        console.log(string)
        resolve() // 추가된 부분
    },
    Math.floor(Math.random() * 100) +1
    )
  })
}

function func2 (){
 func1("1번")
 .then(() => { // 추가된 부분
    return func1("2번")
 })
.then(() => {
    return func1("3번")
 })

}

하나씩 알아보자


promise의 3가지 상태

프로미스는 다음과 같은 3가지 상태가 있다.

대기(pending): 이행하거나 거부되지 않은 초기 상태.
이행(fulfilled): 연산이 성공적으로 완료됨.
거부(rejected): 연산이 실패함.

대기

대기는 초기 상태로, 실행하기 전 상태를 뜻한다.

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

이렇게 만들어 놓은 상태를 대기라고 한다.

이행

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

이행은 resolve나 reject를 실행시키면 이행이다. resolve()안에 들어갈 값은 앞으로 우리가 정해주면 된다.

거부

new Promise(function(resolve, reject) {
	reject(new Error('에러'))
	
});

이행이 성공적으로 완료되면 resovle()의 값을 나타내고, 중간에 문제가 생기면 reject()의 값을 나타내게 된다.


Promise Chaining

Promise Chaining은 여러 개의 promise 함수를 .then()으로 연결시키는 것을 말한다.

여기 각각 func1~4까지 0.5초 뒤에 1번~4번을 뱉는 함수가 있다.
얘네들을 .then()으로 이어주면 비동기 함수들의 결과를 내가 원하는 순서대로 조작할 수 있다.

함수들을 .then()으로 이어준 모습이다.then은 쉽게 말하면 "그리고 나서 이거 실행해" 정도로 나는 이해하고 있다.

.then()안에 return 을 하면 return의 값은 다음 .then(return)이렇게 인자로 들어가게 된다.


요런식으로 결과 값을 다음 .then()에 넘겨주어 +1을 계속 만들어 줄 수도 있다.

profile
코딩하는 공자

2개의 댓글

comment-user-thumbnail
2020년 12월 24일

약속은 지키라고있는겁니다 명심하십쇼

답글 달기
comment-user-thumbnail
2020년 12월 24일

공자님 가르침을 주세요

답글 달기