Software Engineering

동기(Synchronous), 비동기(Asynchronous)

JO_turn 2020. 11. 14. 22:49

일반적으로 우리는 물건을 살 때 오프라인 매장에서 사거나, 온라인 매장에서 산다.

 

오프라인 매장에서 물건을 살 때, 우리는 다른 일을 하지 못한다.

클라이언트에서 서버에 요청을 했을때, 클라이언트는 서버에서 하는 일을 기다린다.

=> 동기적 호출(blocking)

 

온라인 매장에서 물건을 살 때, 우리는 주문해놓은 뒤 다른 일을 할 수 있다.

클라이언트에서 서버에 요청을 했을때, 클라이언트는 서버에서 하는 일을 기다리지 않아도 된다.

=> 비동기적 호출(non-blocking)

 

자바스크립트 내에는 setTimeout() 이라는 대표적인 내장 비동기 함수가 있다. 

setTimeout()은 두 개의 인자를 받는데, 첫 번째 인자에는 콜백함수가 들어가고,

두 번째 인자에는 실행하고자 하는 시간을 받는다.

//즉, setTimeout() 함수는 시간이 흐른 뒤, 콜백함수를 실행한다.

//setTimeout(function() { // Code here }, delay);

//순차적이 아닌, 실행하고자 하는 시간에 따라 실행하므로 비동기 호출이다.

 

const printString = (string) => {
    setTimeout(
        () => {
            console.log(string)
        },
        Math.floor(Math.random() * 100) +1
    )
}
//랜덤의 시간이 흐른 뒤 문자열을 콘솔에 찍는 함수 선언

const printAll = () => {
    printString('a')
    printString('b')
    printString('c')
}
//printSting를 세 번 실행하는 함수선언

printAll(); //b, c, a
printAll(); //a, b, c
printAll(); //b, c, a
//결과는 랜덤한 문자열로 콘솔에 찍힌다.

이처럼 랜덤의 순서를 가지고 있는 함수를 제어하는 방법.

 

1.callback함수 이용하기

const printString = (string, callback) => {
    setTimeout(
        () => {
            console.log(string)
            callback()
        },
        Math.floor(Math.random() * 100) +1
    )
}
//랜덤의 시간이 흐른 뒤 문자열을 콘솔에 찍는 함수 선언
//인자로 callback를 추가해준다.

const printAll = () => {
    printString('a', () => {
      printString('b', () => {
        printString('c', () => {})
      })
    })
}
//printSting를 콜백함수로 받아 실행하는 함수 선언 

printAll(); //a, b, c
printAll(); //a, b, c
printAll(); //a, b, c
//콜백함수로 받아 실행하였기 때문에 a-b-c순으로 콘솔로그에 찍힌다.

***콜백함수를 계속 실행해주어야 하기 때문에 '콜백지옥'에 빠질 수 있다.

 

2.Promise 이용하기_콜백지옥 벗어나기

const printString = (string) => {
  return new Promise((resolve, reject) => {
    setTimeout(
        () => {
            console.log(string)
            resolve()
        },
        Math.floor(Math.random() * 100) +1
    )
  })
}
//랜덤의 시간이 흐른 뒤 문자열을 콘솔에 찍는 함수 선언

const printAll = () => {
    printString('a')
    .then(() => {
      return printString('b')
    })
    .then(() => {
      return printString('c')
    })
}
//a를 찍는 작업이 끝내면 then을 이용하여 다음 작업을 수행하게 한다.

printAll(); //a, b, c
printAll(); //a, b, c
printAll(); //a, b, c
//결과는 a-b-c 순으로 콘솔로그에 찍힌다.

Promise는 객체로 비동기 작업의 최종 완료 (이행 또는 거부)와 그 결과 값을 나타낸다.

//클래스의 인스턴스를 만들듯이, new Promise()를 통해서 생성한다.

 

Promise의 특징 세가지

대기(pending) : 이행하거나 거부되지 않은 초기의 상태.

이행(fullfiled) : 연산이 성공적으로 실행됨.

거부(rejected) : 연산이 실패하여 실행되지 않음.

 

Promise의 메서드

Promise.all(iterable) : 모든 프로미스를 이행한다. 인자는 배열의 형태이다.

//Promise.all([P1, P2, P3,...])

Promise.race(iterable) : 가장 먼저 이행되거나 거절되는 프로미스 객채를 반환한다.

인자는 배열의 형태이다.

//Pormise.race([P1, P2, P3,...])

Promise.reject() : 연산이 거부됐을 경우(error)를 반환한다.

//.catch와 연결된다

Promise.resolve() : 연산이 이행됐을 경우를 반환한다.

//.then과 연결된다.

//어떤 값이 프로미스인지 아닌지 알 수 없는 경우,

//resolve(value) 후 반환 값을 프로미스로 처리할 수 있다.

 

Pormise.prototype

Promise.prototype.catch() : 실패한 비동기 요청을 받아서 반환한다.

Promise.prototype.then() : 성공한 비동기 요청을 받아서 반환한다.

//체이닝이 가능하다.

.then(resp => {
  return
})
.then (____ => {
첫 번째 댄에서 리턴된 값이 두 번째 댄에 들어간다.
})

Promise.prototype.finally() : 마지막에 실행한 값을 반환한다.

 

promise도 callback와 마찬가지로 promise hell을 발생할 수 있다.

하지만 then의 사용을 위의 예제처럼 return을 적절히 사용해주면 지옥을 탈출할 수 있다.

 

3.async await 이용하기_프로미스지옥 벗어나기

const printString = (string) => {
  return new Promise((resolve, reject) => {
    setTimeout(
        () => {
            console.log(string)
            resolve()
        },
        Math.floor(Math.random() * 100) +1
    )
  })
}
//랜덤의 시간이 흐른 뒤 문자열을 콘솔에 찍는 함수 선언

const printAll = async() => {
    const one = await printString('a')
    const two = await printString('b')
    const thr = await printString('c')
}
//async를 이용하여 함수 선언을 한 뒤
//await를 이용하여 실행 순서를 정한다.

printAll(); //a, b, c
printAll(); //a, b, c
printAll(); //a, b, c
//결과는 a-b-c 순으로 콘솔로그에 찍힌다.

async, await 키워드는 Promise 객체에서만 사용 가능하다.

'Software Engineering' 카테고리의 다른 글

Web Architectures(웹 시스템의 구성)  (2) 2020.11.15
node.js module 사용법  (0) 2020.11.14
고차함수(Higher order function) in Javascript  (0) 2020.11.14
HTML  (0) 2020.11.12
Linked List in Date structure  (4) 2020.11.10