[ES6] 8. 동기/비동기 & 콜백함수/promise

지렁·2023년 10월 1일
0

⭐ 자바스크립트는 항상 동기식 처리 (synchronous)

자바스크립트는 single threaded language
➡️ 한번에 코드 하나밖에 실행 못함
➡️ 병렬 불가

자바스크립트를 실행하는 웹브라우저는 stack이라는 코드 실행 공간이 있는데 거기서 코드를 한줄한줄 차례로 실행한다

⭐ 비동기적인 처리도 가능 (asynchronous)

오래걸리는 작업이 있으면 다른 것부터 처리하는 방식
➡️ setTimeout , 이벤트리스너, ajax 함수 등등으로


웹 브라우저 덕분에 가능
만약 setTimeout 같은 코드를 만나면 잠시 Web API 로 옮겨서 대기시킨다
그리고 대기시간이 끝나고 setTimeout이 완료되면 대기실에서 코드를 꺼내서 실행시킨다

만약 파이썬으로 시간 차 출력을 하면

print(1)
time.sleep(1)
print(2)
  • 1-> (1초 후) -> 2

하지만 자바스크립트에서는

console.log(1);
setTimeout(function(){}, 1000);
console.log(2);
  • 1과 2 동시 출력
    1 출력하고 1초뒤에 2가 출력되지 않는다

🤔 이유는?

자바스크립트는 실행까지 조금 시간이 걸리는 함수를 발견하면 제쳐두고 다른코드부터 실행하려고 한다
➡️ 이것이 비동기 이다

🤔 순차적으로 실행시키기 위해서는?

📢 콜백함수 사용

왼쪽 요소가 끝나길 기다렸다가 실행시키고 싶은 코드들 작성

console.log(1);
setTimeout(function(){console.log(2)}, 1000);
  • 1 출력 -> (1초 후) -> 2 출력

콜백함수 디자인 하는 법

function one(){
  console.log(1)
}

function two(){
  console.log(2)
}

one();
two();

만약 첫쨰함수 실행 후 둘째함수를 실행시키고 싶다면?

파이썬으로 코드짠다면 이게 맞지만 자바스크립트는 비동기라는 특수성으로 인해 이렇게 쓴다고 순차적으로 실행하는걸 보장하진 않는다
(첫째함수가 setTimeout 등 Web API 대기실로 보내는 코드라면 나중에 실행될 수 있기 때문)

그렇다면 콜백함수로 만들면 된다
첫째함수(둘째함수)

 function one(func) {
        console.log(1);
        func();
      }
      function two() {
        console.log(2);
      }
      one(two);

이렇게 미리 만들어놓은 함수를 넣어도 되고

one(function(){
  console.log(2)
}):

함수선언문을 직접 파라미터 자리에 입력해도 된다
!
(함수 파라미터에 들어간 함수가 바로 콜백함수)

여러개 콜백함수를 만들면 흔히 콜백지옥이라는 코드를 볼 수 있다

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

➡️ 콜백 대신 Promise 사용

첫째함수().then(function(){
   그 담에 실행할거
}).then(function(){
   그 담에 실행할거
});

⭐ Promise 디자인 패턴

순차적 실행을 위해 콜백함수 대신 쓸 수 있는 코딩 패턴

콜백함수와 차이

  1. 코드 예쁘게 작성 가능
  2. 성공/실패의 경우에 맞춰 다른 코드 작성 가능
var promise = new Promise(function (resolve, reject) {
  var math = 1 + 1;
  resolve(math);
});

promise
  .then(function (res) {
  console.log("성공" + res);
})
  .catch(function () {
  console.log("실패");
});

📢 promise 의 특징

  1. new Promise()로 생성된 변수를 통해 현재 상태 알 수 있음
  • 성공하면 resolved
  • 판정 대기중이면 pending
  • 실패하면 rejected
  1. promise동기 -> 비동기로 바꿔주는 것이 아니다
    콜백함수의 대체품이다
    ex) jquery 의 ajax , js의 fetch

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


promise 예시

Q1. 이미지 로딩 성공시 특정 코드를 실행하기

var imgloading = new Promise(function (resolve, reject) {
  $("#test").load(function () {
    resolve(); //성공하면 성공함수 실행
  });
  $("#test").error(function () {
    reject(); //실패하면 실패함수 실행
  });
});

imgloading
  .then(function () {
  console.log("성공");
})
  .catch(function () {
  console.log("실패");
});

프로미스 안에서는 성공( ), 실패( )가 실행되는 경우의 수를 만들어주면 되고 이제 .then( ) .catch( )를 이용해서 성공/실패시 특정 코드들을 실행한다

Q2. Ajax 요청이 성공하면 무언가 코드를 실행하기

jquery로 ajax 요청하는 방법

$.ajax({
  type : 'GET',
  url : 'URL 경로'
})
//or
$.get('URL 경로')
var loading = new Promise(function (resolve, reject) {
  $.get("https://codingapple1.github.io/hello.txt").done(function (data) {
    resolve(data);
  });
});

loading
  .then(function (res) {
  console.log("성공 메세지 : " + res);
})
 

done 으로 url data를 파라미터로 받아오고 성공 시 reslove를 통해넘겨준다. 그러면 loading이 성공했을 때의 콜백함수에 resolve 에서 넘겨준 값을 파라미터로 받아와서 실행하게 된다

Q3. Promise chaining

var promise = new Promise(function (resolve, reject) {
        $.get("https://codingapple1.github.io/hello.txt").done((data) => {
          resolve(data);
        });
      });

      promise
        .then(function (res) {
          console.log("성공 메세지 : " + res);
          // 새로운 promise 객체
          var promise2 = new Promise(function (resolve, reject) {
            $.get("https://codingapple1.github.io/hello.txt").done((data) => {
              resolve(data);
            });
          });
          return promise2;
        })
        .then((res) => {
          console.log(res);
        });
  1. 첫프로미스가 성공하면 then() 안의 코드를 실행시켜줍니다.
  2. 근데 거기 안에는 프로미스2가 있습니다. 프로미스2가 성공하면
  3. 뒤에 있는 then() 안의 코드를 실행시켜줍니다.
profile
공부 기록 공간 🎈💻

0개의 댓글

관련 채용 정보