기본 콘텐츠로 건너뛰기

1월, 2024의 게시물 표시

Promise.race

  Promise race는 promise끼리 경주를 시킨다고 보면 될 것 같다. 같은 기능의 api를 중복 호출 하는 경우 const delay = (ms) => new Promise ((resolve) => setTimeout (resolve, ms)); async function searchApiv1 () { await delay ( Math . random () * 5000 ); return 'searchApiv1' } async function searchApiv2 () { await delay ( Math . random () * 5000 ); return 'searchApiv2' } const res = await Promise . race ([ searchApiv1 (), searchApiv2 ()]) console . log ( res )  자 위의 코드를 잠깐만 살펴보자, searchApiv1, searchApiv2은 각각 5초이내에 완료가 되는 api라고 보면 된다. 둘 중 하나의 api의 결과만 필요한 경우, 위처럼 작성하면 된다.  뭐 물론 위와 같은 코드를 짤만한 상황이 그렇게 많지는 않을 것이다. 조금 현실적인 예제를 보도록 하자. 클라이언트 에서의 api타임아웃 구현 const delay = (ms) => new Promise ((resolve) => setTimeout (resolve, ms)); async function searchApi () { await delay ( Math . random () * 5000 ); return 'searchApiv1' } async function requestTimeout (ms) { await delay (ms) throw 'request time out' } try { const res = await Promise . race ([ search

setTimeout, setInterval을 이용한 호출 스케줄링

 setTimeout: 일정 시간이후에 함수를 실행 시켜준다.  setInterval: 일정 시간마다 함수를 실행 시켜준다.  자 생각을 해보자, 특정 시간마다 alert을 띄워주는 함수이다.  특정 시간마다라고 생각해보면, setInterval을 생각 할 수 있다. setInterval (() => { alert ( 'called' ) }, 1000 )  자 이렇게 작성 하게되면 어떤 이슈가 있을까? 여기서 문제는 alert이 띄워진 상태에서도 시간이 지나고, 1초마다 콜백 실행이 태스크큐에 쌓인다는 것이 문제이다.  그러면 어떻게 해야 할까? function setIntervalTimeout (cb, ms) { return setTimeout (() => { cb(); return setIntervalTimeout (cb, ms) }, ms); } setIntervalTimeout (() => alert ( 1 ), 1000 )  위처럼 사용 하면, interval 처럼 사용 하면서, alert이 종료된 이후에 스케쥴링을 등록을 하기 때문에, alert이 종료 된 이후에 스케쥴을 등록하게 되어, alert이 중첩실행 되지 않게 수정이 가능하다.  하지만 위에서 문제는... clearTimeout이 불가능 하다는 것이다. 자 그러면 어떻게 해야 할까? function setIntervalTimeout (cb, ms) { const ret = {} ret . timeoutSeq = 0 ; ret . timeoutSeq = setTimeout ( function run () { cb(); ret . timeoutSeq = setTimeout ( run , ms) }, ms); return ret } const test = setIntervalTimeout (() => alert ( 1 ), 1000 ) clearT

함수 정의 어떤기준으로 할까?

 함수를 만들 때, 대부분의 사람들이 고민을 하게 된다. 이 정도로 짧은 라인일 뿐인데 혹은 한번밖에 쓰이지 않는 로직인데, 함수로 정의해야 할까?  이런 고민을 하는 이유는 프로그래밍을 배우면서, 함수에 대한 정의를 배우기 때문(?)일 것 같다.  - 함수(function), 서브루틴(subroutine), 루틴(routine), 메서드(method), 프로시저(procedure)는 소프트웨어에서 특정 동작을 수행하는 일정 코드 부분이다. 즉, ' 특정한 작업을 위해 재활용할 수 있도록 구현한 코드 블록 '을 의미한다.  재활용할 수 있도록 구현한 코드 블록. 솔직히 나는 이 재활용이란 단어를 왜 넣었는지, 이해가 되지 않는다. 재사용도 아니고... 재활용이라니...  한국어가 아닌 영어로도 보자.  - Functions may be defined within programs, or separately in libraries that can be used by many programs. In different programming languages, a function may be called a routine, subprogram, subroutine, or procedure; in object-oriented programming (OOP), it may be called a method. Technically, these terms all have different definitions, and the nomenclature varies from language to language. The generic umbrella term callable unit is sometimes used.  단지 실행 가능한 단위일 뿐이다. recylce이라던지, reuse라던지 우리가 아는 단어가 없다.  자 그러면 잠깐 아래의 코드를 잠깐만 보도록 하자. async function updateEmail (userId, email) { const

continue, break, label 사용해야 할까?

 반복문을 사용하다보면, continue, break를 사용해야 하는 경우가 있다. break의 개념은 순회함수에서도 가끔 사용 되는 경우가 있는데, 아래와 같은 경우이다. let res = 1 ; for ( let i = - 8 ; i < 20 ; i++) { res *= i ; if (! res ) break; } res = 1 ; [ 1 , 2 , 4 , 5 , 2 , 3 , 1 , 0 , 2 , 3 , 1 ]. every (i => { return res *= i ; }) 개인적으로는 싫어하는 방식이지만.. every와 some의 경우 return을 이용하여, break처럼 사용할 수 있다.  일반적으로는 label을 사용해본 경험이 있는가? 웬만하면, c언어에서 이런 문법도 있어요~ 수준으로 소개를 할 뿐 스파게티 소스가 되기 때문에 label을 사용한 경험은 웬만해서는 없을 것이다.  continue와 label을 합친 방식은 continue가 순회문에서만 사용가능 하기 때문에, 큰 의미는 없으나, label과 break를 합친 방식은 사용하려면 해볼 수 는 있다.  break와 label을 합친 빠른리턴, function foo (str) { if ( typeof str !== 'string' ) return; // 추가적인 로직 console . log ( '실행되지 않음' ) ; } const str = null; bar: { if ( typeof str !== 'string' ) break bar ; // 추가적인 로직 console . log ( '실행되지 않음' ) ; } console . log ( '여기는 실행 된다.' ) ;  함수라면, 더이상 실행 되지 않아야 하는 구간에서는 return;을 사용 하여, 실행을 중지 할 수 있지만, 평가 중 부분만 건너뛰어야한다면, 위처럼 break와 lebel을 사용하여, 건너뛰는 것