728x90

bundler

webpack bundler의 역할

bundler를 쓰지않는다면?

  • 브라우저에서 페이지를 load 할때 많은 파일들이 로드 된다. 일반적으로 서버와의 접속이 많을수록 어플리케이션이 느려지게되는 문제점이 생기기때문에 매우 비효율적이다.
  • bundler가 없다면 아래에서 처럼 요청을 보낼때마다 해당 페이지에서 사용하는 resource(js,html,jpg,css)마다 각각 하나의 파일 단위로 로드하기 때문에 매우 비효율적이다. 
    • 만약 하나의 파일을 로드하는데 2초가 걸리고 resource가 총 5개 있다고하면 하나의 페이지를 여는데 10초가 걸리게 된다. (비동기 가정)

 

bundler 이란

  • 위에서의 비효율성을 해결하기위해 소프트웨어 및 일부 하드웨어와 함께 작동하는 데 필요한 모든 resource을 포함하는 패키지를 만들어 하나의 파일로 관리하도록 도와주는 라이브러리이다.
    • 위의 5개의 resource가 존재하는 페이지를 로드하는 상황에서 걸리는 시간은 2~3초 정도로 줄게 될 것이다.
  • 특히 서로다른 패키지들이 같은 이름과 같은 변수를 사용하면서 어플리케이션이 깨지게되는데 이를 해결해 준다.
    •  
    • //index1.html <!DOCTYPE html> <html> <head> <title>Document</title> <script> let duplicated = 1;</script> </head> <body> </body> </html> //index2.html <!DOCTYPE html> <html> <head> <title>Document</title> <script src="./index1.html"> let duplicated = 1;</script> // 변수 중복지정으로 인한 에러 발생 </head> <body> </body> </html>
    • 기본적으로 import시 모듈 개념이 잡혀있지않다. import 'asdf.js'
      • import마다 index.html에서 < script type="module">import asdf from 'asdf.js' </script>을 해줘야한다.
        • 하지만 webpage에서는 매 import되는 자원마다 download를 하게되어 load가 많이 생기게된다. --> 하나로 묶어주고싶다.
    • 여러개의 파일을 묶어주는 도구 --> webpack, broserify,parcel등이 해당
  • 여러가지 모듈들을 몰아넣고 성능향상을위해 다시 분리할 수 있다. 이외에도 최적화등을 위한 다양한 확장 기능들이 존재

 

 

'Webpack' 카테고리의 다른 글

Package-lock.json  (0) 2021.07.27
Package.json dependencies versioning  (0) 2021.07.27
Bundle Diet  (0) 2021.07.26
728x90
  var let(const)
scope function-scope block-scope
hoisting yes no
global-object yes no
redeclaration yes no

1. function scope vs block scope

javascript에서 scope란 변수가 사용될 수 있는 범위를 뜻한다.

이를 근거로, function scope란 변수가 활용될 수 있는 범위가 function임을 뜻하고

block scope는 변수가 활용될 수 있는 범위가 { }(block)임을 뜻한다.

 

var로 선언된 변수는 function scope 속성을 가지고 있어 선언된 function 내에서라면 어디서든 사용할 수 있는 반면

let(또는 const)로 선언된 변수는 block scope 속성을 가지고 있어 선언된 block 내부에서밖에 사용할 수 없다.

See the Pen scope by zakelstorm (@zakelstorm) on CodePen.

2. Hoisting

hoisting은 변수가 초기화 되는 시점과 관련되어있다.

어떤 변수에 hoisting이 발생했다면 이는 코드 시작점에서 해당 변수가 undefined로 초기화 되었음을 뜻한다.

 

var로 선언된 변수는 hoisting 속성을 가지고 있어 선언된 function 내부에서라면 선언되기 이전이라도 사용될 수 있다.

반면에 let(또는 const)으로 선언된 변수는 hoisting 속성을 가지고 있지 않아 선언된 시점에 초기화되기 때문에 선언된 시점 이후부터 사용될 수 있다. 

See the Pen hoisting by zakelstorm (@zakelstorm) on CodePen.

3. create global object property

global object란 window object에 저장되어 있어 어디서든 사용가능한 object안 value를 뜻한다.

예를들어 대표적인 global object 중 하나는 alert가 되겠다.

 

코드의 top level에서 var로 선언된 변수는 global object가 되는 속성을 가지고 있어 전역변수 처럼 어디서든 쓸 수 있다. let으로 선언되었거나 함수 내부에서 선언된 var 변수는 window object에 추가되지않는다.

 

See the Pen global object property by zakelstorm (@zakelstorm) on CodePen.

4. Redeclaration

var 변수는 재선언이 가능하다.

반면 let변수는 재선언이 불가능하다.

var foo = "foo1";
var foo = "foo2"; // No problem, 'foo' is replaced.

let bar = "bar1";
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared

'Javascript' 카테고리의 다른 글

Image Lazy Loading  (0) 2021.07.24
prototype  (0) 2021.02.14
비동기 처리 - async/await  (0) 2020.12.27
비동기 처리 - Promise  (0) 2020.12.20
동기/비동기 처리 - Callback, Callback 지옥  (0) 2020.12.20
728x90

지금까지 회사업무로 인해 issue 관리 툴로 atlassian의 jira를 사용해 왔다. 팀원들간 개발내역 및 내가 하고 있는 일을 쉽게 공유 할 수 있기때문에 협업 프로젝트를 하면서 꼭 필요한 툴이라고 생각한다.

 

하지만 큰 프로젝트가 아닌 작은 프로젝트를 하는데 과연 다른 사이트에 회원가입 및 스페이스를 따로 열면서 까지 해당 툴로 이슈 관리를 해야할 필요가 있을지 의문을 가지게 되었다.

 

마침 깃으로도 이슈관리를 할 수 있다는 사실을 알았고 깃을 이용한다면 Repository 를 여는 순간 이슈관리 스페이스를 따로 생성할 필요가 없고 별도의 회원가입 및 프로젝트 팀원의 권한관리를 할 필요가 없다는 점에서 작은 프로젝트를 하기엔 jira보다 편할것이라고 생각했다.

 

그럼 깃으로 프로젝트를 관리하는 방법을 평소 하나의 이슈가 발급되고 닫힐때 까지 과정을 바탕으로 순서대로 알아보도록 하자.

 

1. 이슈 발급

 - 이슈 탭 활성화 및 이슈 템플릿(양식) 생성

  먼저 이슈를 발급하기 위해서는 먼저 깃에 이슈 발급 환경을 구성해야한다.

 

  세팅에 들어가서 이슈 탭 활성화 및 템플릿을 설정하도록한다.

 

 이슈 탭 활성화
이슈 템플릿 생성

  여기서 추가되는 템플릿은 나중에 이슈 생성 시 등록 양식으로 사용할 수 있다.

  Bug report와 Feature request 템플릿은 깃에서 제공하는 템플릿이고

  Custom issue template은  사용자가 직접 작성한 양식을 지정할 수 있는 템플릿이다.

 - 이슈 발급

  이슈 발급은 다음과 같이 하면된다.

 

이슈발급

  이후 위에서 지정한 추가한 템플릿을 선택 후 이슈 내용을 작성하여 이슈를 발급하면된다.

 

2. 이슈 관리

  이슈를 열었으면 이제 이슈를 관리할 수 있어야한다.

  이슈 관리의 핵심 요소는 크게 다음과 같다.

  • Asignee : 이슈 해결을 전담 받은 사람
  • Labels : 이슈 카테고리 (ex, bug, new feature, question
  • Status : 이슈의 상태 (ToDo, In Progess, Done)

  먼저 Asignee와 Label은 이슈 생성단계 및 Issue 설정 정보에서 등록/수정 가능하다.

Asignee & Labels 등록 

 Status 관리를 위해서는 Project(jira에서는 Epic에 해당) 등록을 한다. Project는 Jira에 Epic 해당한다고 보면 좋다. Jira의 Epic은 task(issue) 의 모음이다.

 각 이슈는 Project에 등록을 할 것이며 각 이슈의 status 또한 Project 내에서 관리하게 될 것이다.

 

 git Repository안에 프로젝트를 생성한다

프로젝트 생성

생성된 Project내에 Add column 버튼을 사용하여 Project내 등록된 이슈의 관리 방식(Status)을 정의한다. 일반적으로는 Todo, In Progress, Done의 3단계 형식으로 관리한다.

 

이 때 내가 Project에 등록한 Issue의 status를 Isuue 또는 Pull Request가 Open됐는지 Close 됐는지에 따라 자동으로 바꿀 수 있게 지정할 수 있다. 이 기능을 깃에서는 Manage automation이라 부른다. 

Issue Status 정의

이제 다시 Issue 돌아와 새로 생성된 Project에 해당 Issue를 등록하도록 한다. 만약 Issue를 새로 생성할 단계라면 생성 화면에서 Project에 할당할 수 있다. 

 

만약 해당 이슈에 대한 개발을 바로 시작할 것이라면 Project의 Isuue Status Dropdown을 눌러 해당 이슈의 status를 IN PROGRESS로 바꿔주면 된다. 그렇지 않다면 TO DO에 넣으면 된다. 

Project 등록 및 이슈 status 등록

 

3. Pull Request

특정 이슈의 Asignee가 개발을 끝낸 후 Repository에 해당 이슈에 대한 commit을 push 한후 Pull request가 발생했다.

깃에서는 Jira에서와 마찬가지로 이 Pull Request 또한 이슈와 연동할 수 있다.

Jira는 commit 메시지의 제목을 읽어 자동으로 연동해주는 반면 깃은 commit message의 제목을 읽지않고 subMessage를 읽어 해당 연동작업을 할 수 있다.

 

PullRequest와 Issue의 연동을 위한 Commit subMessage의 구성은 기본적으로 다음과같다.

● [keyword]: #[이슈번호]

[keyword]는 Pull request의 특정 액션에 따라 Issue를 처리할 방식을 결정할 메시지고,

[이슈번호]는 해당 Pull Request와 연동하고자하는 이슈번호다.

이렇게 commit message로 연동한 이슈는 연동된 Pull Request를 merge할 때 자동으로 close 된다.

 

해당 Pull Request가 어떤 성격을 지녔는가에 따라 다르게 keyword를 선택하면된다. (보통의 기능 추가라면 keyword 로 resolves를 사용하고 이미 만든 기능의 버그 수정이라면 fix를 사용하면된다.)

 keyword의 종류는 다음과 같다.

  • close
  • closes
  • closed
  • fix
  • fixes
  • fixed
  • resolve
  • resolves
  • resolved

 

'Git' 카테고리의 다른 글

version tag 원칙  (0) 2021.03.28
cherry-pick 필요 상황 및 사용법  (2) 2020.12.29
728x90

평소 git branch, checkout, add, commit, pull, push, reset, rebase, merge, stash 와 git IDE으로 부족함 없이 git을 사용하여 왔기 때문인지 git 명령어에 대한 공부가 게을러졌다.

저 위의 명령어들외에 그나마 빈번히 쓰였던 cherry-pick에 대해 알아보고 어떤 상황에서 사용하는지 어떻게 사용하는지 알아보자.

 

cherry-pick이란

cherry-pick이란 다른 브랜치 위에 있는 커밋을 선택적으로 내 브랜치에 적용시킬 때 사용하는 명령어이다.

 

좀더 쉽게 그림으로 설명하자면

다음과 같이 commit 상황을 가지는 Master 브랜치와 Feature 브랜치가 있다. 

 a - b - c - d   Master
         \
           e - f - g Feature

Master 브랜치에 Feature의 e와 g를 뺀 f 커밋만 merge 하고 싶다.

이 경우 cherry-pick을 사용하지 않고 f 커밋만 merge 할 수 있을까?

1. git checkout Feature; git rebase master; git checkout master; // 사전 rebase 처리

2. git merge Feature //master에 Feature branch 가져오기

a - b - c - d - e - f - g   Master
         \
           e - f - g Feature


3. git reset --hard f //master g commit 삭제

a - b - c - d - e - f   Master
         \
           e - f - g Feature


4. git reset --soft e //master f commit 해제 및 코드변화 가져오기

a - b - c - d - e   Master (staged: f code changes)
         \
           e - f - g Feature


5. git stash //master f 코드변화 따로 저장 및 보호

a - b - c - d - e   Master (git stash list: f code changes)
         \
           e - f - g Feature


6. git reset --hard d //master e commit 삭제

a - b - c - d   Master (git stash list: f code changes)
         \
           e - f - g Feature


7. git stash pop //master f 코드변화 불러오기

a - b - c - d   Master (staged: f code changes)
         \
           e - f - g Feature


8. git commit f 

a - b - c - d - f   Master (staged: f code changes)
         \
           e - f - g Feature

최소 총 8번씩이나 git 명령어를 입력해야 이를 해결 할 수 있다. 이를 cherr-pick 을 사용한다면 단 한번의 명령어로 원하는 커밋을 merge 할 수 잇다.

1. git checkout master

2. git cherry-pick 76ae30ef // 76ae30ef: Feature f commit의 id

다른 브랜치의 커밋을 그대로 가져온다는 점에서 rebase와 개념적으로 겹치는 부분이 있다. 그래서 rebase를 사용할 줄 안다면 더욱이 cherry-pick이 없는 불편함을 크게 느끼지는 못했을 수 있다.

하지만 프로젝트 규모가 크고 많은 사람들이 코드를 수정하여 변화가 빈번하다면 rebase만으로는 한계가 있을 수 있다. cherry-pick을 기억해두도록 하자.

 

cherry-pick 필요한 상황 및 사용 이유

그럼 cherry-pick을 어떤 경우에 사용하게 될까?

기본적으로 수정해야 할 commit이 다른 commit들 사이에 껴있는 경우와 같이 수정 시 많은 reset을 필요로 할 때 cherry-pick이 빛을 발한다.

  1. 커밋을 다른 브랜치에 잘 못했을 때 이를 뒤늦게 찾은 경우
  2. 요구사항이 바뀌어 필요없는 커밋이 생겼을 경우
    • 해당 커밋들을 빼고 cherry-pick
  3. 수정사항이 생겨 두개의 브랜치에 동시 commit 해야할 경우
    • 어느 한 브랜치에 커밋 후 다른 브랜치에서 cherry-pick
  4. 코드 의존성 때문에 다른 사람의 커밋 중 일부를 가져와야 할 경우

'Git' 카테고리의 다른 글

version tag 원칙  (0) 2021.03.28
git으로 프로젝트 관리하는 방법 - Issue 관리  (0) 2021.01.09
728x90

복잡한 then chaining도 코드를 난잡하게 만들기 마련이다.

그래서 Promise를 좀 더 간결하고 간편하고 동기적으로 실행되는 것처럼 보이게 만들어주는 syntactic sugar로 async/await 을 사용한다

syntactic sugar란?
  • 사람이 이해 하고 표현하기 쉽게 디자인된 프로그래밍 언어 문법

  • 사람이 프로그래밍 언어를 sweeter하게 사용 할 수 있도록 도와주는 문법

  • 더욱 더 간결하고 명확하게 표현이 가능한 문법

// 비동기 처리를 하지 않은 경우
function fetchUser(){
	//do network request in 10 sec
    return 'asdf'
}

const user  = fetchUser();
console.log(user);

이 경우 javascript는 기본적으로 동기적으로 코드를 실행하기때문에

network작업이 promise가 아닌 경우라면 10초를 기다린 후 console log에 asdf를 띄우게 된다.

화면을 띄운다고 할때 이렇게 기다린 후 출력하는 것은 매우 비효율적이기에 우리는 그동안 Promise로 이러한 현상을 해결해 왔다.

 

// async
async function fetchUser(){
	//do network request in 10 sec
    return 'asdf'
}

const user  = fetchUser();
console.log(user);

async를 도입하였다. async를 사용하는 방법은  함수 앞에 async를 붙이면 끝이다.

이 경우 이 함수는 자동으로 Promise를 반환하는 함수가 된다.

 

// await
function delay(ms){
	return new Promise(resolve=>setTimeout(resolve,ms));
}

async function getApple(){
	await delay(3000);
    return 'apple'
}

async function getBanana(){
	await delay(3000);
    return 'banana';
}

/* then을 사용했다면
function getBanana(){
  delay(3000).then(()=>{
  	return 'banana';
  });
}
*/
	

 async가 Promise를 대신했다면 await는 then을 대신한다.

직관적으로 then을 썼을때보다 이해하기 편하다.

 

// async await 도입
async function pickFruits(){
	const apple = await getApple();
	const banaa = await getBanana();
    return `${apple} + ${banana}`;
}

pickFruits().then(console.log);

Promise/then을 대신하여 async/await을 도입한 경우이다. 이 경우 총 6초를 기다린후 `apple + banana` 를 반환받게 된다.

하지만 getApple()과 getBanana()는 서로 독립적인 함수이므로 서로를 기다려 반환 받을때까지 6초씩이나 걸릴 필요가 없다. 이러한 문제를 어떻게 처리할 수 있을까 방법은 다음과 같다.

 

async function pickFruits(){
	const applePromise = getApple();
    const bananaPromise = getBanana();
    const apple = await applePromise();
    const banana = await bananaPromise();
    return `${apple} + ${banana}`
}

pickFruits.then(console.log);

이전 시간에 Promsie는 선언과 동시에 실행된다고 배웠다. 이러한 Promise의 특성을 이용하여

getApple()과 getBanana()를 일단 동시에 실행시킨후 ( await(then) 을 붙이지 않은 Promise이기 때문에 서로를 기다리지 않는다)

뒷 줄에 이 실행 시킨 함수들이 각각 return 값 반환 할때까지 기다린다.

그 이 후 성공적으로 3초만 기다린 후 `apple + banana`를 반환한다.

 

그렇다면 만약 이런 병렬적으로 처리해야할 함수가 많다면 각 함수마다 일일히 이런 방식으로 처리해줘야할까?

이 경우 Promise의 내재함수를 사용하면 쉽게 해결 할 수 있다.

 

function pickAllFruits(){
	return Promise.all([getApple(),getBanana]);
    .then(fruits => fruits.join(' + '));
}

pickAllFruits().then(console.log);

Promise.all은 병렬적으로 실행해도 되는 Promise 함수를 동시에 실행하여 모든 return값을 반환받을때까지 기다린 후 then을 실행한다.

만약 Promise 함수중 하나라도 error(reject)가 발생하면 다른 응답을 기다리지 않은채 catch 구문으로 가게된다.

만약 이것이 싫고 모든 값을 반환받을때까지 기다리고 싶다고 한다면 Promise.all 대신 Promise.allSettled를 사용하면된다. 

'Javascript' 카테고리의 다른 글

prototype  (0) 2021.02.14
var vs let (const)  (0) 2021.01.13
비동기 처리 - Promise  (0) 2020.12.20
동기/비동기 처리 - Callback, Callback 지옥  (0) 2020.12.20
ECMA Script 2020 (ES11)  (0) 2020.12.13
728x90

callback을 대체하여 비동기를 간편하게 처리할 수 있도록 도와주는 object.

정해진 장시간의 기능을 시행하고나서 정상적으로 동작했다면 성공 메시지 전송, 실패했다면 에러 메시지 전송.

 

promise는 두가지 포인트만 알고 가면 이해하기 편하다

  1. state : 시행하고 있는 중인지, 성공했는지 실패했는지의 상태 (pending -> fulfilled or rejected)
  2. producer & consumer : 정보를 제공하는 producer(promise 생성) 소비하는 consumer(promise 실행)로 나눌 수 있다.

Producer

새로운 Promise는 생성되는 순간, 안에 있는 executer callback function을 자동으로 실행하게 된다. 

See the Pen Promise by zakelstorm (@zakelstorm) on CodePen.

위의 상황에서 먼저 첫번째 경우를 보면 다음과 같은 특징을 가지고 있다.

  1. new Promise가 선언됨 시점에서 Promise내부의 callback함수가 실행됨.
  2. promise.then을 3번 호출해도 Promise내부의 callback함수가 실행되지 않음.

이와 같은 특징에서

Promise는 외부에서 선언과 동시에 callback 함수가 실행이 되며

이 Promise 선언을 대입받은 변수(promise)는 Promise가 resolve 한 값을 받게 되어 해당 변수에 then을 붙여 실행하여도 기다림 없이 then의 callback함수를 실행하게 된다.

 

이를 사용자가 원하는 시점에 Promise를 실행하고 원하는 then callback함수 실행 시점을 만들기 위해

코드의 두 번째 경우에서 처럼  Promise를 함수에 감싸 함수 실행하듯 사용하면 위의 문제를 해결할 수 있다.

Consumer

실행된 promise에 대해 then, catch, finally를 이용하여 resolve 또는 reject 된 값을 가져올 수 있다.

resolve와 reject는 각각 then, catch에 대응되며 사용방법은 다음과 같다.

const producer = new Promise((resolve,reject)=>{
  console.log('doing someting...')
  setTimeout(()=>{
    resolve('success');
  },2000)
})

producer.then(value=>{
  console.log(value); // resolve value인 'success'를 출력
})

const producer2 = new Promise((resolve,reject)=>{
  console.log('doing someting...')
  setTimeout(()=>{
    reject('fail');
  },2000)
})

producer2.then(value=>{
  console.log('then') //성공적인 case만 출력하므로 then구문은 타게되지않는다.
  console.log(value); 
}).catch(value=>{
  console.log('catch') // reject되는 순간 catch 구문을 타게된다.
  console.log(value);// resolve value인 'fail'를 출력
})

then은 promise를 반환하기 때문에 이 뒤에 catch 또는 then을 또 한 번 호출할 수 있다. 이를 chaining이라고 한다.

 

Promise chaining

const fetchNumber = new Promise((resolve,reject)=>{
  setTimeout(()=>{
    resolve(1),1000
  })
})

fetchNumber
  .then(num => num*2) // 2, num*2 앞에 (return)이 생략되어 있다
  .then(num=>num*5) // 10
  .then(num=>{
    return new Promise((resolve,reject)=>{
      setTimeout(()=>{
        num-=7; 
        resolve(num); // 3
      },1000)
    })
  })
  .then(num=>{
    console.log(num) // 3
  })
;

then은 일반적인 return 또는 promise resolve를 바로 전달할 수 있다. (then 또한 Promise 값을 return 하기 때문)

이러한 점덕분에 위 코드에서 (return) num 또는 resolve(num) 값이 뒤의 then으로 넘어간 것이다.

 

Error Handling

const getHen = () =>{
	new Promise((resolve,reject)=>{
    	setTimeout(()=>resolve('myhen'),2000);
    });
}

const getEgg = (hen) =>{
	new Promise((resolve,reject)=>{
    	setTimeout(()=>reject(`${hen} => myegg`),2000);
    });
}

const cook = (egg) =>{
	new Promise((resolve,reject)=>{
    	setTimeout(()=>resolve(`${egg} => myfried egg`),2000);
    });
}
 
 // return값을 그대로 한개의 함수로 바로 넘긴다면 다음과 같이 parameter생략가능
 getHen
   .then(getEgg)
   .then(cook)
   .then(console.log) //어떠한 것도 출력되지않음
   
 getHen
   .then(getEgg)
   .then(cook)
   .then(console.log)
   .catch(console.log) // Error메시지와 함께 myhen => myegg 출력
   
 //전체적인 promise chain에 문제가 생기지 않도록
 getHen
   .then(getEgg)
   .catch(error =>
   	return 'mybread'
   )
   .then(cook)
   .then(console.log) // mybread => myfried egg 출력
   .catch(console.log) 

catch는 이전의 Promise chain에서 reject 반환 시 실행되는 구문이다.

 

javascript에서는 catch의 위치를 적절히 대입하여 error에 대응할 수 있다.

catch 구문 뒤의 then은 앞의 catch 구문에서 에러를 처리한 후에도 계속 이어서 실행되며,

catch 뒤의 catch의 실행 시점은 앞의 catch와 뒤의 catch사이에서 error가 생겨야 비로소 실행이 된다.

 

Callback 지옥 해결

이전의 Callback지옥을 해결한 버전은 다음과 같다. then을 중첩해서 쓰는 과오를 범했었는데 then을 중첩해서 쓰면 callback지옥과 결국 비슷한 의미가 된다. 가능한 떨어뜨리도록 하자.

See the Pen VwKrEOw by zakelstorm (@zakelstorm) on CodePen.

'Javascript' 카테고리의 다른 글

prototype  (0) 2021.02.14
var vs let (const)  (0) 2021.01.13
비동기 처리 - async/await  (0) 2020.12.27
동기/비동기 처리 - Callback, Callback 지옥  (0) 2020.12.20
ECMA Script 2020 (ES11)  (0) 2020.12.13
728x90

Synchronous vs Asynchronous

Synchronous

기본적으로 자바스크립트는 Synchronous 하다.

그러므로 hoisting(var, function declaration을 제일 위로 올리는 것) 후 코드를 한줄한줄 순서대로 실행한다.

Asynchrous

Asynchrous 코드는 언제 실행될지 예측할 수없다.

예를 들어 setTimeout 함수 안에 하나의 파라미터 인자로 만든 함수를 전해준다. 당장 실행하지 않고 브라우저에게 일정 시간이 지난 후 callback을 실행하게 해주는 기능이 내재되어있다. 이것이 asynchrnous execution의 기본이다.


Synchronous callback function vs Asynchronous callback function

callback function은 모두 asynchronous할까?

그렇지 않다.

 

callback function에도 callback function을 바로 실행하는 synchronous callback function과

callback function이 언제 실행될지 예측할 수 없는 asynchronous callback function이 존재한다.

See the Pen Synchrnous vs Asynchrnous by zakelstorm (@zakelstorm) on CodePen.


callback 지옥

callback function이 중첩적으로 쓰여 callback이 매우 nesting 된 형태. callback 안에 callback이 있고 그 callback 안에 또 callback이 있는 매우 알아보기 힘든 코드. 이를 유지할 시 유지 보수력이 떨이지게 된다.

 

callback 지옥의 코드를 만들어보았다.

로그인 기능을하는 frontend 코드이며, backend가 존재하지 않기때문에 해당 비동기 처리는 setTimeout( )으로 대체하였다.

 

코드의 구성은 다음과 같다.

  1. 사용자가 id, password 입력
  2. 입력된 id, password로 login (loginUser이용)
  3. login 이후 바로 해당 id의 role 반환(loginUser 함수 안에 onSuccess 이용)
  4. 반환된 role 출력 (getRoles 이용)

See the Pen callback 지옥 by zakelstorm (@zakelstorm) on CodePen.

callback function이 어떻게 돌아가는지 확실히 알기 위에서는 코드를 일반적으로는 우리가 머릿속에 코드를 외우기 힘들기 때문에 왔다갔다해서 봐야할 것이다. 이유는 다음과 같다.

  • loginUser
    • loginUser안 onSuccess에는 user=>{ userStorage1.getRoles(user, ... , ...) } 가 대입된다.
    • onSuccess에서는 id를 parameter로 쓰고있다. 즉, callback function의 user에 id가 대입된다.
  • getRoles
    • getRoles안 onSuccess에는 userWithRole=>{ alert(...); }가 대입된다.
    • onSuccess에서는 {name:'ASDF', role:'admin'}을 parameter로 쓰고있다. 즉, callback function의 userWithRole에 {name:'ASDF, role:'admin'}이 대입된다.

이렇게 대입 방향이 실행 코드(loginStorage1)~정의 코드(loginStorage)사이에서 엉키게 된다.

callback function에 parameter가 존재하면, 코드를 이해하기 위해서는 계속 실행코드와 정의코드로 왔다갔다 해야한다. 이러한 callback function이 nesting 되는 형태가 복잡하다면 이것이 콜백 지옥이다.

 

이를 해결하는 방법이 바로 Promise와 async/await 이다. return 값이 생기게 됨으로서 대입 방향을 단방향으로 만들게 된다.

 

'Javascript' 카테고리의 다른 글

prototype  (0) 2021.02.14
var vs let (const)  (0) 2021.01.13
비동기 처리 - async/await  (0) 2020.12.27
비동기 처리 - Promise  (0) 2020.12.20
ECMA Script 2020 (ES11)  (0) 2020.12.13
728x90
  • 배운 기술을 가지고 놀자
    • 놀다보면 궁금한게 많아지게 된다 찾아가며 공부하자
  • 배운 기술을 가치르치자
    • 배우자와 대화하는 것, 블로그에 글을 쓰는것

10단계 학습법

  • 기본개념

    1. 출발점: 배우려하는 기술을 사용하기 위해 알아야 할 기본적인 사항은 무엇인가?
    2. 학습범위: 배워야하는 범위는 어느정도 인가? 배운내용을 어떻게 활용할 수 있는가? 그 기술로 어떤 일을 할 수 있는지 큰 그림을 볼 수 있으면 된다.
    3. 기본 사용법: 기본적인 이용사례와 가장 흔하게 접하는 상황은 무엇인가? 80퍼센트 비중으로 사용하게될 20퍼센트의 핵심 기술은 무엇인가?
    • 위에 3가지를 알면 어떤 기술이든 쓸 수 있다. 나머지는 차차 익힌다. 이를 위해 10단계 학습법을 적용한다.
  • 1단계: 큰 그림을 봐라

    • 무엇을 모르는지 주제의 범위가 얼마나 넓은지
      • 인터넷 검색등으로 짧은 시간동안 배울 주제에 어떤 내용들이 있는지 범위가 어느정도 되는지 큰그림을 보아라
  • 2단계: 범위를 정하라

    • 집중적으로 학습할 영역을 명확히 한다.
      • 어떤 영역에 집중해서 어느 정도 범위까지 배울지 미리 정해야한다.
    • 1단계에서 모은 정보를 활용해서 배우고자 하는 영역을 적당한 크기로 줄인다.
  • 3단계: 성공을 정의하라

    • 도달할 성공을 명확하고 간결하게 한문장으로 정의한다.
  • ex) C#의 주요 기능을 활용해서 간단한 응용 프로그램을 만들겠다. HTML5를 활용해서 이력서와 포트폴리오를 담은 내 홈페이지를 만들겠다.

  • 4단계: 자료를 찾아라

    • 선택한 주제에 대해 최대한 다양한 자료를 찾아보도록 노력하라
      • ex) 유투브, 책, 블로그, 프로젝트사례
  • 5단계: 학습 계획을 세워라

    • 자신만의 학습 순서를 찾아라.
      • 학습 순서는 책의 목차와 매우 비슷하다. 책의 순서를 참고하자
  • 6단계: 자료를 선별하라

    • 목표 달성에 도움이 될 가치 있는 자료만 고른다. 어떤 책또는 블로그를 볼지
  • 7단계: 대충 사용할 수준까지 배워라

    • Hello World 같은 기본 프로그램 만들기나 개발 환경을 설정하는 단계
  • 8단계: 놀아라

    • 원하는것 무엇이든 해보라.
      • 자료를 꼼꼼히 보기전에 대상을 가지고 놀며 실험해본다.
  • 9단계: 유용한 일을 할 정도까지 배워라

    • 잃어버린 호기심을 되찾는다.
      • 모든 자료를 찾아보며 학습 대상을 깊이 있게 이해한다.
      • 8단계에서 궁금했던 질문의 답을 찾는다.
  • 10단계: 가르쳐라

    • 블로그글, 유투브 동영상, 발표, 대화, 온라인 포럼에 답글달기

'Books' 카테고리의 다른 글

프로그래머, 열정을 말하다  (0) 2022.12.26
소프트 스킬 2  (0) 2020.12.13
소프트 스킬 1  (0) 2020.12.13

+ Recent posts