본문 바로가기

개발몰입과정 개념스터디/3차

JavaScript의 비동기 기술

동기와 비동기란?(작업 완료 여부를 누가 신경쓰느냐)

  • 동기 방식은 서버에서 요청을 보냈을 때 응답이 돌아와야 다음 동작을 수행할 수 있다. 즉 A작업이 모두 진행 될때까지 B작업은 대기해야한다.
  • 비동기 방식은 반대로 요청을 보냈을 때 응답 상태와 상관없이 다음 동작을 수행 할 수 있다. 즉 A작업이 시작하면 동시에 B작업이 실행된다. A작업은 결과값이 나오는대로 출력된다.

 

blocking/non-blocking(바로 return하느냐 마느냐)

  • 호출된 함수가 바로 return해서 호출한 함수에게 제어권을 넘겨주고호출한 함수가 다른 일을 할 수 있는 기회를 줄 수 있으면 non-blocking이다.
  • 호출된 함수가 자신의 작업을 모두 마칠 때까지호출한 함수에게 제어권을 넘겨주지 않고 대기하게 만든다면 blocking이다.

 

 


[참고]https://brash-wanderer-5cd.notion.site/js-callback-Promise-async-await-95ed43531dcb4c93b23380bbc32c58b4

 

https://velog.io/@daybreak/동기-비동기-처리

https://velog.io/@wonhee010/동기vs비동기-feat.-blocking-vs-non-blocking

 

 


js 비동기처리(callback, Promise, async, await)

js는 setTimeOut을 실행하거나 서버에서 데이터를 가져오는 등, 오래 걸릴 일들을 기다리지 않고 다음 일부터 처리한다. 이때문에 비동기화가 되고 다시말해 비동기화는 특정 연산이 끝나기 전 이를 기다리지 않고 다음 코드를 먼저 실행하는 것을 말한다.

코드로 살펴보자면 아래 예시에서 데이터를 가져오는 작업을 기다리지 않고, 다음 작업인 console.log를 먼저 실행했기 때문에 undefined가 나오는 현상이다.

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

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

 

비동기식처리와 콜백함수

이런 js의 비동기를 처리하기 위해 콜백함수를 사용한다. 콜백 함수는 특정 코드가 끝난 후 원하는 동작을 실행시킨다.

function getData(callbackFunc) {
	$.get('<https://domain.com/products/1>', function(response) {
		callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
	});
}

getData(function(tableData) {
	console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});

getData에서 서버와 통신해 받은 resopnse를 getData 함수가 끝난 후, callback함수에 넘겨준다. 그리고 callback함수에서 console.log를 바로 실행시킨다.

 

Promise (resolve, reject, .then, .then.catch)

Promise는 서버에서 데이터를 가져오거나 setTimeOut등 비동기가 일어날 객체이다.

  • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
  • Fulfilled(이행&완료) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
  • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

비교하기(callback, Promise)

callback함수를 사용해 비동기처리를 한 것

unction getData(callbackFunc) {
  $.get('url 주소/products/1', function(response) {
    callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
  });
}

getData(function(tableData) {
  console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});

 

Promise를 사용해 비동기처리를 한 것

function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});

 

Pending(대기)

Promise만 선언

new Promise();

또는 Promise 속 callback함수 선언

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

 

Fulfilled(이행&완료) (=처리 결과값을 then으로 보내기)

콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행(Fulfilled) 상태가 됩니다.

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

이행 상태가 되면 아래와 같이 then()을 이용하여 처리 결과 값을 받을 수 있다.

function getData() {
  return new Promise(function(resolve, reject) {
    var data = 100;
    resolve(data);
  });
}

// resolve()의 결과 값 data를 resolvedData로 받음getData().then(function(resolvedData) {
  console.log(resolvedData);// 100});

 

Rejected(실패)

reject를 아래와 같이 호출하면 실패(Rejected) 상태가 됩니다.

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

실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있습니다.

function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("Request is failed"));
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
  console.log(err);// Error: Request is failed});
});

resolve와 reject를 then, then.catch로 잡기

function getData() {
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      if (response) {
        resolve(response);
      }
      reject(new Error("Request is failed"));
    });
  });
}

// 위 $.get() 호출 결과에 따라 'response' 또는 'Error' 출력
getData().then(function(data) {
  console.log(data); // response 값 출력
}).catch(function(err) {
  console.error(err); // Error 출력
});

 

Async, Await

개발자가 보기 편하도록 만든 최신 비동기처리방법

//기본 문법
async function 함수명() {
  await 비동기_처리_메서드_명();   //다음으로 넘어가지 않고 바로 실행되도록 함.
}

 

callback함수 사용해 비동기처리를 한 것

function logName() {
  // 아래의 user 변수는 위의 코드와 비교하기 위해 일부러 남겨놓았습니다.
  var user = fetchUser('domain.com/users/1', function(user) {
    if (user.id === 1) {
      console.log(user.name);
    }
  });
}

 

async&await사용해 비동기처리를 한 것

// async & await 적용 후
async function logName() {
  var user = await fetchUser('domain.com/users/1');
  if (user.id === 1) {
    console.log(user.name);
  }
}

 

기본 예제

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]
}

fetchItems는 Promise객체를 반환하고 reslove는 처리결과를 logItems에 넘긴다.

 

 


[참고]

https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

'개발몰입과정 개념스터디 > 3차' 카테고리의 다른 글

Class Component vs Functional Component  (0) 2022.02.05
React Virtual Dom란?  (0) 2022.02.05
JWT란?  (0) 2022.02.05
CORS란?  (0) 2022.02.05
TypeScripts란?  (0) 2022.02.05