기본 콘텐츠로 건너뛰기

12월, 2020의 게시물 표시

비동기 코드를 처리 하자

 이번 포스트에서는 비동기처림에 대한 간단한 처리만 해보고 넘어 가고자 한다. callback, promise, async await을 모르는 분만 읽기를 바라며 그저 간단하게 사용법을 소개 하는 포스트이다.  웹 개발뿐만 아니라 네트워크로 통해서 들어오거나 외부 레거시 코드를 실행하는 경우, 즉시 값이 리턴을 받지 않고, 해당 네트워크 혹은 레거시에서 처리후 callback을 통하여 실행 되는 경우가 많다.  이러한 경우를 처리를 해보자. function getDir ( path , callback ) { if ( typeof callback === 'function' ) { setTimeout ( () => { callback( [ 'Documents' , 'Download' , 'Etc' ] ) } , 1000 ) } }  위 처럼 해당 path에 있는 폴더들을 확인 하고 그 폴더들가지로 callback을 호출해주는 코드이다.  우린 위처럼 콜백 함수를 넣어서 순회를 할 수 있다.  예전에 구현해둔 map을 이용해서 적절하게 순회도 가능하다.  자 그렇다면 test 폴더안에서 Etc 폴더를 찾아서 그 안의 폴더인 Donwload 폴더를 찾아보면 어떤 코드가 될까?  위와 같이 표현이 될 수 있다. 그렇다면 점점 더 상세한 폴더가 필요 하게 되면 어떻게 될까?  즉 test/Etc/Download/Download/Download/Download/Download/Download 처럼 말이다.  코드는 점점 안쪽으로 들어가서 코드가 파악하기가 점점 복잡해진다. 위는 그나마 간단한 요구 조건이라서 덜 복잡해보이는 감이 있다.  getDir에다가 Promise를 입혀보자. function getDirPromise ( path ) { return new Promise (resolve => { getDir ( path , resolv

1000만 개 중에 2개 주세요(게으른 평가)

 요구조건으로 이런것이 왔다고 쳐봅시다.  서비스 개발한 서비스의 사용자의 데이터에서 포인트의 누적을 자신의 가족 수를 곱하고 그 값이 1000점 이상인 사람들 중에서 해당 포인트의 제곱근이 소수점을 버리고 홀 수 인 사람 중에 두사람의 마지막 계산된 포인트를 뽑아달라는 요청이 왔다.  ( 말도 안되는 시나리오지만 아 그렇구나 하고 넘어가자. )  일단 저 2명을 뽑기 위해서 take라는 함수를 구현해봅시다.   const take = ( count , iter ) => { const res = [] for ( const item of iter ) { res. push ( item ) if ( res. length === count ) return res } return res } 잘 동작 합니다. 고객 정보가 없기 때문에 적당히 고객정보를 구현 할 수 있도록 range도 구현을 해봅시다. const range = ( limit ) => { const res = [] let count = 0 while ( count < limit ) { res. push ( count++ ) } return res } 이제 샘플로 사용 할 고객 정보를 임의로 만들 수 있도록 함 수 하나를 만들겠습니다. 위 시나리오상 가족수랑 포인트만 있으면 되겠네요. const genMember = () => { return { family : Math . ceil ( Math . random () * 8 ) , point : Math . ceil ( Math . random () * 8000 ) } } 적당히 만들었습니다. 그러면 이제 1000만명을 만들어서 위의 로직을 돌려보도록 하죠. 저의 PC가 못버티는 관계로... 10만명으로 하겠습니다. const members = go ( range ( 1000000 ) , map ( genMember ) ) 간단하게 이처럼 처리하면 됩니다. 이제 위

map, filter, reduce (go, curry)

 간단하게 map, filter, reduce를 구현해보자. 1. map은 인자를 두개를 받으며, 첫번째 인자를 받아서 두번째 인자로 평가 후 배열로 리턴해준다. const map = ( iter , func ) => { const ret = [] for ( const item of iter ) { ret. push ( func( item ) ) } return ret }  위와같이 간단하게 짤 수 있다. 2. filter를 구현해보자 map과 두개의 인자를 받으며, 첫번째 인자를 받아서 두번째 인자로 평가 후 값이 있다며 배열로 리턴을 해준다. const filter = ( iter , func ) => { const ret = [] for ( const item of iter ) { if ( func( item ) ) { ret. push ( item ) } } return ret }   3. reduce는 세개의 인자를 받으며, 첫번째 인자를 받아서 두번째 인자로 받은 함수로 평가하며 축적된 값을 리턴을 한다, 이때에 세번째 인자를 초기값으로 이용한다. const reduce = ( iter , func , acc ) => { for ( const item of iter ) { acc = func(acc , item) } return acc }  이와 같이 표현 할 수 있지만, 초기값을 안넣은 경우에는 iter의 첫번째 값을 초기값으로 사용하게 변경 해보자. const reduce = ( ...args ) => { let iter = args[ 0 ] const func = args[ 1 ] let acc = args[ 2 ] if ( args. length < 3 ) { iter = iter[ Symbol . iterator ]() acc = iter. next (). value } for ( const item

for of (feat.iterable)

 ES6부터 새로 생겨난 for of에 대해서 궁금증이 생겨서 학습안 내용을 포스트에 남깁니다. const arr = [ 1 , 2 , 3 , 4 ] for ( const value of arr ) { console . log ( 'value' , value ) } const set = new Set ([ 1 , 2 , 3 , 4 ]) for ( const value of set ) { console . log ( 'value' , value ) } const obj = { 0 : 1 , 1 : 2 , 2 : 3 , 3 : 4 } for ( const value of obj ) { console . log ( 'value' , value ) } Array, Set은 for of 문장으로 반복이 되지만, Object는 반복이 되지 않는가? obj is not iterable 인데, 반복할 수 없다 정도록 해석이 가능 할 것 같다. for of구문을 확인해보면 아래와 같다. iterable이 무엇인가? 간단하게 말하면 iterator를 생성할 수 있는 모든객체를 말 할 수 있다. 그러면 iterator는 무엇인가? 반복자를 말한다. 저 단어는 많은 개발자들이 많이 들어 보셧을 것이기 때문에 이하 생략한다. 여기서 더 중요한것은 for of는 무엇을 반복자로 받아 들이는가? 이다. 이에 대한 내용은 ES6에 추가된  protocol인   iterable protocol 과 iterator protocol을 확인 할 필요가 있다. 이 기준에만 충족을 한다면 자바스크립트의 for of에 적용 할 수 있다. protocol 두가지는 아주 심플하다. iterable protocol: 내용을 살펴 보면 Object 혹은 prototype chain 의 오브젝트 중 하나가 Symbol.iterator key의 속성을 가지며 값이  iterator protocol을 충족 시킬수 있는 값을 반환하는 함수를