오늘은 현업 개발자 분께 2주간 진행할 프로젝트의 git 주소를 clone 받아 초기세팅을 완료하였고, 개발자분이 미리 뼈대로 작성해주신 코드를 읽어보며 모르는 부분을 학습하였다.
그 중 비동기 처리에 대해 공부를 할 수 있게 되었다.
비동기를 처리하는 프로그래밍에는 아래 3가지 방식을 쓸 수 있다.
> 동기? vs 비동기?
동기 : 코드가 반드시 작성된 순서대로 실행 (단일 선로)
비동기 : 쓰레드나 프로세스가 여럿이 돌고 있다.
비동기작업을 먼저 마친 후 콜백함수를 실행한다고 생각하면 된다!
function first() { let value; value = { name: "WooYoung", age: 32 }; return value; } console.log(first()); // { name: "WooYoung", age: 32 }
여기에 setTimeout 함수를 적용해보면
function first() { let value; setTimeout(() => { value = { name: "WooYoung", age: 32 }; }, 1000); //타이머가 만료된 뒤 실행 return value; } console.log(first()); // undefined
변수 value에 객체를 할당하기 전에 반환했기 때문에
반환된 값은 undefined
이다.
하나의 예시를 더 보자.
비동기작업을 먼저 마친 후 콜백함수를 실행한다고 생각하면 된다!
몇 초간 통신을 통해 서버에서 가지고 온 데이터를 활용하려면
즉, 비동기 함수를 통해서 얻어진 데이터를 어떻게 핸들링할 수 있을까?
> 콜백 함수
말 그대로 나중에 호출할 함수
function first(callback) { let value; setTimeout(() => { value = { name: "WooYoung", age: 32 }; callback(null, value); }, 3000); } first(function (error, value) { if (error) { // ErrorHandling } else { console.log(value); // { name: "WooYoung", age: 32 } } });
ErrorHandling : 데이터 송신이 실패할 가능성은 언제나 있기 때문에 에러를 핸들링 해야 한다.
first 함수의 인자로 콜백함수를 넘겨주고 비동기 처리가 끝난 후, 콜백함수를 실행하여 정상적으로 데이터를 가지고 왔다.
> Callback Hell
first(function callbackOne(error, value) { if (error) { // ErrorHandling } else { second(value, function callbackTwo(error, value) { if (error) { // ErrorHandling } else { third(value, function callbackThree(error, value) { if (error) { // ErrorHandling } else { console.log(value); } }); } }); } });
에러 핸들링을 각 콜백함수마다 해줘야하기 때문에 가독성이 떨어진다.
콜백 함수는 다른 코드의 인자로 넘겨줌으로써 제어권 또한 위임한 함수이다.
즉, 콜백 함수 호출 시점의 권한이 개발자에게 있는 것이 아니라 제어권을 넘겨받은 코드에게 있다는 것이다.
> Promise
then : 프로미스가 이행(fulfilled)되었을 때 실행되는 함수
첫번째 인자(함수)는 Promise의 성공 결과 값catch : 프로미스가 거부(error)되었을 때 실행되는 함수
첫번째 인자(함수)는 Promise의 거부 결과 값
function getFirstUser() { return getUsers().then(function(users) { // getUsers()는 promise를 리턴 return users[0].name; }).catch(function(err) { return { name: 'default user' }; }); }
어떤 작업의 중간상태를 나타내는 오브젝트
미래에 어떤 종류의 결과가 반환됨을 promise (약속) 해주는 오브젝트
Promise란 비동기 작업이 종료된 후,
성공 혹은 실패했는지
그럼 성공 or 실패의 결과 값이 무엇인지
위 내용을 미래(비동기 작업이 종료된 후)에 반환해주겠다고 약속해주는 객체이다.
> async / await
try...catch : 오류 처리
async
함수를 실행하게 되면 무조건 Promise
객체가 반환된다.
await
키워드는 Promise
객체를 생성하는 함수 앞에 놓을 수 있다.
자바스크립트가 await
키워드를 만나게 되면
Promise
상태가 이행될 때까지 기다렸다가
이행이 완료되면 그 결과 값을 반환하고 다음 코드를 실행한다.
promise에서 .then()
을 쓰는 것과 동일!!
async function getFirstUser() { try { let users = await getUsers(); //Promise값이 사용가능할때까지 await return users[0].name; } catch (err) { return { name: 'default user' }; } }
try
에서 어떤 곳에서든지 에러가 발생하면 제어 흐름이 catch
로 넘어간다.