12월28일 개발 블로그(콜백,프로미스,async await,styled-component naming)

npm audit fix

Run a security audit

audit:보안감사의 기능

프로젝트 root 경로에서 nmpm audit을 입력하면 프로젝트에서 사용하고 있는 모듈의 취약점에 대해서 알려준다.

styled Component naming 규칙

  1. 최상위 부모
  • ‘컴포넌트명’Layout 이란 이름으로 생성
  1. 최상위 부모의 자식 (최상위 부모의 바로 하위 요소)
  • '컴포넌트명'Row or '컴포넌트명'Col 이란 이름으로 생성
  • Row나 Col 이라는 네이밍의 실질적인 태그는 divsection 태그등이 될 수 있음
  • Row는 가로, Col은 세로!
    • 둘 다 실제 태그는 div여도, css로 flex-direction등을 변경해서 가로 or 세로를 변경해주면?flex-direction이 row 라면 Rowcolumn 이라면 Col
  • 최상위 부모가 대분류의 느낌이라면, 이 요소는 소분류의 느낌

3)나머지 요소들

  • 네이밍 예시 (예시일뿐! 특정 태그의 의미와 부합된다면 됨!)
    • div 태그: '컴포넌트명'Box
    • section 태그: '컴포넌트명'Section
    • ul 태그: '컴포넌트명'List
    • li 태그: '컴포넌트명'Item
    • p 태그: '컴포넌트명'Paragraph
    • span 태그: '컴포넌트명'Span or '컴포넌트명'Text
  • 어떻게보면 큰 규칙은 없는 것, 제일 많이 쓰일 것임!

4) 참고!

  • 1) 과 3) 의 설명들은 optional 적인 규칙이 아닙니다! 지켜주세요!
  • 예시 html
<div> <!-- 1. Layout -->
    
<div> <!-- 2. Row / Col (optional) -->
<div> <!-- 3. Box -->
<ul> <!-- 3. List  -->
<li> <!-- 3. Item  -->
<span>Text</span> <!-- 3. Text  -->
</li>
</ul>
</div>
</div>
    
<div> <!-- 2. Row / Col (optional) -->
<div> <!-- 3. Box -->
<ul> <!-- 3. List  -->
<li> <!-- 3. Item  -->
<span>Text</span> <!-- 3. Text  -->
</li>
</ul>
</div>
</div>
    
</div>
    

await, async

장점:

  • 프로미스의 단점 보완(=단점은 뭐였을까?)
  • 가독성 증가

예시

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

async & await 기본 문법

asnyc function 함수명() {
	await 비동기처리_메서드명();
}

함수의 앞에 asnyc라는 예약어를 붙인다.

함수의 내부 로직 중 HTTP통신을 하는 비동기 처리 코드 앞에 await를 붙인다.

💡 주의점: **비동기 처리 메서드**가 **꼭 프로미스 객체를 반환**해야 await가 의도한대로 동작함

일반적으로 await의 대상이 되는 비동기 처리 코드Axios등 프로미스를 반환하는 API 호출 함수

async await 간단 예제

function fetchItems() {//fetchItems를 Promise 객체를 반환해주는 함수로 만든다.
  return new Promise(function(resolve, reject) { 
    var items = [1,2,3];
    resolve(items)
  });
}

async function logItems() {
  var resultItems = await fetchItems(); //promise객체를 반환해주는 함수 부분에 await 사용
  console.log(resultItems); // [1,2,3]
}

자바스크립트 async와 await

Promise

promise란?

Javascript 비동기 처리에 사용되는 객체

promise가 필요한 이유

  • 프로미스:주로 서버에서 받아온 데이터화면에 표시할 때 사용
  • 데이터를 다 받아오기 전에 데이터를 다 받아온 것 마냥 화면에 데이터를 표시하려는 것을 방지하기 위함

프로미스 코드-기초

아래 코드는 원래 ajax 통신이다.

function getData(callbackFunc) { //파라미터로 콜백함수가 들어간다
  $.get('url 주소/products/1', function(response) { //function(tableData)가 function(response)의 기능을 담당하고 tableData=response가 된다.
    callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
  });
}

getData(function(tableData) { //콜백함수로 function(tableData)가 쓰였다.
  console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});

이를 프로미스로 바꾸면 아래와 같다

function getData(callbackFunc) {
// new Promise 객체 추가
	**return new Promise(function(resolve, reject) {**
	$.get('url주소', function(response) {
//데이터를 받으면 resolove() 호출한다.
		**resolve(response);**
}};
});
}
//getData()의 실행이 끝나면 호출되는 then()
getData()**.then**(function(tableData){
//resolve()의 결과 값이 여기로 전달된다.
	console.log(tableData); //$.get() 의 response 값이 tableData에 전달된다.
})

프로미스의 3가지 상태

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

Pending

아래와 같이 new Promise() 메서드를 호출한 경우 pending 상태가 된다.

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

특징으로는 아래와 같습니다.

  • 콜백 함수 선언 가능
  • 콜백 함수의 인자는 resolve,reject

Fulfilled

reslove를 실행하면 이행(fulfilled)상태가 된다.

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

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

//then 사용 예시
function getDate() {
return new Promise(function(resolve,reject) {
	var data = 100;
	resolve(data);
});
}

getData().then(function(resolvedData) {
	console.log(resolvedData); //100
}//resolvedData 함수에 있는 resolvedData에 resolve의 결과값을 받아온다.

Rejected(실패)

new Promise()로 프로미스 객체를 생성하면 콜백 함수 인자로 resolve와 reject를 사용할 수 있다고 했다.

여기서 reject를 사용하는 경우에는 호출 실패가 된다. 또한 실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있다.

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

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

getData().then().catch(function(err) {
	console.log(err); //Error:Request is failed
});

프로미스 코드 예시

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 출력
});

여러 개의 프로미스 연결하기(Promise Chaining)

프로미스의 또 다른 특징:여러 개의 프로미스를 연결하여 사용 가능

then() 메서드를 호출하고 나면 새로운 프로미스 객체가 반환된다. 따라서 아래와 같이 코딩이 가능하다.

function getData() {
	return new Promise({
	// ...
})
}//데이터 받아오는 함수 선언

// then() 으로 여러개의 프로미스를 연결한 형식
getData()
.then(function(data) {
// ...
})
.then(function() {
// ...
})
.then(function() {
// ...
})

실제 예시는 아래와 같다.

//getData().then 부분 바꿔서 시행
new Promise(function(resolve,reject) {
	setTimeout(function() {
	resolve(1); //성공하면 1 반환
},2000); //2초뒤 실행
})
.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
})

setTimeout():2초 후에 resolve()를 호출하는 예제

resolve()가 호출되면 프로미스가 대기 상태에서 이행 상태로 넘어가기 때문에 첫 번째 .then()의 로직으로 넘어갑니다.

첫 번째 .then()에서는 이행된 결과 값 1을 받아서 10을 더한 후 그다음 .then() 으로 넘겨줍니다. 두 번째 .then()에서도 마찬가지로 바로 이전 프로미스의 결과 값 11을 받아서 20을 더하고 다음 .then()으로 넘겨줍니다. 마지막 .then()에서 최종 결과 값 31을 출력합니다.

  • settimeout으로 2초뒤 실행후 순서대로 1에 10을 더하고 20을 더한뒤 최종 결과값 31을 출력한다.

프로미스 에러 처리 방법

  1. then()의 두번째 인자로 에러 처리
getData().then(
handleSuccess,
handleError
)
  1. catch()를 이용하는 방법

    getData().then().catch();

두가지 모두 reject()메서드가 호출되어 실패 상태가 된 경우에 실행한다.

특히 두가지중에서는 가급적 catch()를 쓰는게 좋습니다.

// then()의 두 번째 인자로는 감지하지 못하는 오류
function getData() {
  return new Promise(function(resolve, reject) {
    resolve('hi');
  });
}

getData().then(function(result) {
  console.log(result);
  throw new Error("Error in then()"); // Uncaught (in promise) Error: Error in then()
}, function(err) {
  console.log('then error : ', err);
});

getData()의 함수의 프로미스에서 resolve() 메서드를 호출하여 정상적으로 로직을 처리했지만, then()의 첫 번째 콜백 함수 내부에서 오류가 나는 경우 오류를 제대로 잡아내지 못합니다.

따라서 이와 같은 에러를 잡지 못했다는 에러가 뜬다.

하지만,똑같은 오류를 catch()로 처리하면 다른 결과가 나온다.

// catch()로 오류를 감지하는 코드
function getData() {
  return new Promise(function(resolve, reject) {
    resolve('hi');
  });
}

getData().then(function(result) {
  console.log(result); // hi
  throw new Error("Error in then()");
}).catch(function(err) {
  console.log('then error : ', err); // then error :  Error: Error in then()
});

비동기 처리와 콜백 함수

비동기 처리란?

특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성

비동기 처리의 사례들

  1. 제이쿼리 ajax
    • ajax: 비동기 자바스크립트와 XML(=Asynchronous Javascript And xml) 서버와 통신하기 위해 XMLHttpRequest 객체를 사용하는 것

      XMLHttpRequest란?

      (직역:xml http 요청) 서버와 상호작용하기 위해 사용된다. 전체 페이지의 새로고침 없이도 URL로부터 데이터를 받아올 수 있다. 웹 페이지가 사용자가 하고 있는 것을 방해하지 않으면서 페이지의 일부를 업데이트 할 수 있도록 해준다.
function getData(){
var tableData; //tableData 변수 선언
$.get('https://domain,com/products/1', function(response) {
tableData = response;
});
return tableData;
}
        
console.log(getData()); //undefined

서버에서 받아온 데이터는 response 인자에 담긴다.

console.log(getData())를 하면 tableData에 대한 값이 나와야 하는데 undefined가 나왔다. 왜 그럴까?

undefined가 나온 이유

비동기라서 그렇다.

비동기는 위에서 공부했듯이, 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하기 때문에, 데이터를 요청하고 받아올 때까지 기다려주지 않고, 다음 코드인 return tableData;를 실행해버렸기 때문에 아무 값이 들어가지 않게 되었다.

즉 비동기 처리란?

특정 로직의 실행이 끝날때까지 기다리는게 아닌, 그 이후의 나머지 코드를 먼저 실행해주는것이 비동기 처리이다.

비동기 처리가 필요한 이유

서버가 언제 요청에 대한 응답을 할 지 모르는데, 다른 코드를 실행을 안하고 응답만 기다리고 있으면, 한 페이지가 실행되는데 수십분이 걸릴수가 있게 되기 때문

  • 즉, 속도를 위해서이다.
  1. setTimeout() 메소드
console.log("hello");
setTimeout(function(){
	console.log("bye");
},3000) //3초뒤 실행
console.log("hello again");
  1. hello실행→3초뒤 bye실행→hello again 실행
  2. hello실행→hello again 실행→코드 실행 3초뒤 bye실행

여기서 정답은 2번이다.

setTimeout()도 비동기 방식이므로, setTimeout()을 실행한 후 바로 console.log(”hello again”);으로 넘어가게 된다.

  1. 사용자 이벤트 처리

브라우저 화면에서 발생하는 사용자의 이벤트는 예측이 불가능하다.

따라서 이런 화면이벤트를 관리담당하는 녀석에게 우리는 특정이벤트가 발생할 때 호출을 원하는 내용을 callback 함수에 전달하게 된다.

  1. 네트워크 응답 처리

화면단에서 서버에게 요청을 보냈을 때, 그 응답이 언제 올지 알 수 없다.

따라서 이런 서버에 대한 응답처리 등도 비동기적으로 처리해야 한다.

  1. 파일 Read,write등의 파일 시스템 작업

콜백 함수로 비동기 처리 방식의 문제점 해결하기

콜백함수란?

  • 앞서 위에서 봤듯이 데이터가 서버에서 받아오지 못하는 것을 해결해준다.
  • 콜백함수를 사용하면 특정 로직이 끝났을 때 원하는 동작을 실행시킬 수 있다.
  • 콜백함수는 데이터가 준비된 시점에만 우리가 원하는 동작을 수행할 수 있다.

콜백함수의 문제점! 콜백 지옥(callback hell)

콜백 지옥은 비동기 처리 로직을 위해 콜백 함수를 여러번 연속해서 사용할 경우 발생하는 문제

$.get('url', function(response) {
	parseValue(response, function(id) {
		auth(id, function(result) {
			display(result, function(text) {
				console.log(text);
			});
		});
	});
});

서버에서 데이터를 받아와 화면에 표시하기까지 인코딩,사용자 인증등을 처리해야 되는 겨우가 있다.

이 모든 과정을 비동기로 처리해야 한다고 하면 위와 같이 콜백 안에 콜백을 계속 무는 형식으로 코딩을 하게 된다.

단점:

  • 코드의 가독성이 떨어짐
  • 로직 변경이 어려워짐

콜백 지옥 해결 방법

해결 방법으로는 Promise와 Async를 사용하는 방법이 존재한다.

코딩 패턴으로만 콜백 지옥을 해결하려면 아래와 같이 각 콜백 함수를 분리시켜서 로직 변경이 용이하도록 만들면 된다.

function parseValueDone(id) {
	auth(id, authDone);
}
function authDone(result) {
	display(result, displayDone);
}
function displayDone(text) {
	console.log(text);
}
$.get('url', function(response) {
	parseValue(response, parseValueDone);
});

참고 블로그:https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

좋은 웹페이지 즐겨찾기