tevelop RSS 태그 관리 글쓰기 방명록
2021-08-30 15:57:42

동기 

한 작업이 완전히 끝나야 다음 작업으로 넘어감

ex)

console.log(1);
console.log(2);
console.log(3);

/**
    1
    2
    3
    1, 2, 3 순서대로 출력된다.
*/

 

비동기 

 한 작업이 끝나지 않고 다음 작업으로 넘어간다.

ex)

console.log(1);

setTimeout(function afterTwoSeconds() {
  console.log(2);
}, 2000);

console.log(3);

/**
  1
  3
  2
  1, 2, (2초 뒤), 3으로 찍힐 것 같지만 1,3,2로 출력된다.
  setTimeout은 비동기 함수이기 때문에!
*/

 

 

 


 

 

 

 

좀 더 쉽게 이해해보자!

ex) 커피숍

▪️ 동기 : 손님 한 명이 주문 후 커피를 받아가는 것 까지 마쳐야 다음 손님의 주문을 받을 수 있다.

▪️ 비동기 : 주문은 순서대로 받는다. 앞 사람이 커피를 받아갔는지는 알 바가 아니다. 커피는 나오는대로 받아가면 된다!

 

 

 

 


 

 

▪️ 자바스크립트 자체는 동기이다.

 

 


 

 

 

비동기 사례

 

ajax

function getData() {
  var tableData;
  $.get('https://domain.com/products/1', function(response) {
    tableData = response;
  });
  
  return tableData;
}

console.log(getData()); // undefined

위의 코드에서 undefined가 찍힌 이유는 ajax 통신은 비동기 방식으로 동작하기 때문이다.

get을 한 뒤 요청 받은 값을 받을 때 까지 기다리지 않고 tableData를 return 시켰기 때문에 undefiend가 찍힌 것.

 

setTimeout()

위에서 비동기를 설명한 코드와 같다.

 

 

 

 


 

 

 

 

 콜백 함수

function getData(cb) {
  $.get('https://domain.com/products/1', function(res) {
    cb(res);
  });
}

getData(function(tableData) {
  console.log(tableData);
});

콜백 함수를 사용하면 특정 로직이 끝났을 때 원하는 동작을 실행 시킬 수 있다.

하지만 콜백 함수로 비동기 처리를 해결하게 되면 엄청난 콜백 지옥에 빠지게 될 수 있다..!

콜백 지옥

 

 

 

 


 

 

 

 

콜백 지옥 탈출 방법 두 가지

 

Promise

・ 프로미스는 자바스크립트 비동기 처리에 사용되는 객체!

위의 예제를 promise를 사용한 예제로 변환해보겠다.

function getData(cb) {
  return new Promise(function(resolve, reject) {
    $.get('url/products/1', function(res) {
      resolve(res);
    });
  });
}

//getData()의 실행이 끝나면 then을 호출된다.
getData().then(function(tableData) { // then에 resolve();된 값이 전달된다.
  console.log(tableData);
});

이렇게 바꿀 수 있다!!

 

Promise 의 사용법에 대해 더 알아보자.

// promise 객체 생성 시, 콜백 함수를 선언 할 수 있다.
// 콜백 함수의 첫번째 인자로는 resolve();
// 두번째 인자로는 reject();가 들어온다.
new Promise(function(resolve, reject) {
  resolve(); // resolve();를 하면 이행 상태가 된다.
  resolve('값'); // resolve안에 값을 넣어 전달하면 - (1)
  reject(); // reject();를 하게 되면 실패 상태가 된다.
  reject(new Error('error')); // 실패 한 이유를 reject()에 넣어 전달하면 - (2)
});

getData().then(function(data) { // then의 첫번째 인자에서 받아 올 수 있다. - (1)
  console.log(data);
}).catch(function(err) { // catch 절에서 에러를 받을 수 있다. - (2)
  console.log(err); 
});

 

프로미스 사용법을 활용한 예제

function getData() {
  return new Promise(function(resolve, reject) {
    $.get('url/products/1', function(res) {
      if(res) {
        resolve(res);
      }
      reject(new Error('error'));
    });
  });
}

getData().then(function(data) {
  console.log(data);
}).catch(function(err) {
  console.log(err);
});

 

여러개의 프로미스 연결

function getData() {
  return new Promise({
    // ...
  });l
}

getData()
.then(function(data) {
  // ...
})
.then(function() {
  // ...
})
.then(function() {
  // ...
});

// then 메서드를 호출하고 나면 새로운 프로미스 객체가 반환된다!
new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve(1);
  }, 2000);
})
.then(function (result) {
  console.log(result); // 1
  return result + 10;
})
.then(function (result) {
  console.log(result); // 11
  return result + 20;
})
.then(function (result) {
  console.log(result); // 31
});

 

 

async / await

콜백과 프로미스의 단점을 보완하고, 코드를 더 읽기 좋게 만들어준다.

async function 함수명() {
  await 비동기_처리_메서드명();
}
function fetchItems() {
  return new Promise(function(resolve, reject){
    var items = [1, 2, 3];
    resolve(items);
  });
}

async function logItems() {
  var resultItems = await fetchItems();
  console.log(resultItems); // [1, 2, 3]
}

 

await은 Promise를 기다리기 위해 사용한다. await은 async function 내부에서만 사용할 수 있다.

 

awiat문은 Promise가 fulfill(연산이 성공적으로 완료)되거나 reject 될 때 까지 async 함수의 실행을 일시 정지하고, Promise가 fulfill 함수를 일시 정지한 부분부터 실행한다. 이때 await 문의 반환값은 Promise에서 fulfill된다.

 

만약 Promise가 reject 되면, await문은 reject 된 값을 throw 한다.

 

 

 

 


참고 출처 : https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/ 시리즈

'Frontend > Javascript' 카테고리의 다른 글

[javascript] 웹 페이지에서 javascript가 하는 일  (0) 2021.09.12
Javascript new  (0) 2021.08.25
Javascript this  (4) 2021.08.13
tevelop. Designed by 코딩재개발.