자바스크립트의 Array에는 함수가 정말 많다. 아니? 디이이이지게 많다.
왠만한건 알아서 쓰지만 가끔 사용법이 기억이 안나면 RunJS에 치곤 하는데요,
그 중에서도 특이한 친구들이 있습니다.
Array.reduce
Array.map Array.forEach
Array.filter
Array.every Array.some
Array.find Array.findIndex
인자로 currentValue(또는 element), index, array를 공통적으로 가진다.
예제를 들어보겠습니다.
언급한 모든 함수들은 세 개의 인자를 공통적으로 가집니다.
currentValue : 현재 순회 중인 아이템의 값 index : 현재 순회 중인 아이템의 인덱스 array : 해당 함수를 호출한 원본 배열
간단하게 설명해서, map은 배열을 반환하고 forEach는 그렇지 않습니다.
두 함수 모두 콜백을 실행합니다만, 배열을 반환하느냐? 하지 않느냐? 에 대한 차이입니다.
주의할 것은 원본 배열을 수정하는 것이 아니라는 점인 것 같습니다.
사용 예) forEach의 경우 - 반복적인 작업이 있고, 그것을 간단히 표현하고 싶을 때. map의 경우 - React에서 동일한 컴포넌트를 반복적으로 그릴 때. - 원본 배열을 통해 새로운 배열을 만들어야할 때.
쉽게 말해서 and와 or의 차이입니다.
and는 모든 조건이 true일 때만 true지만 or은 무언가가 true면 true인 것과 같습니다.
사용 예) every의 경우 - 로그인시 ID, 비밀번호 input이 모두 채워졌는지. some의 경우 - 평가 항목 중 단 하나라도 낙제점이 있는지.
find는 값을 반환하고, findIndex는 해당 값의 인덱스를 반환합니다.
앞서 언급한 함수들과 다르게 reduce는 콜백에 'accumulator'라는 인자를 하나 더 받습니다.
이는 이전에 실행된 콜백의 반환값을 의미하고, 또 누적한 값이라고도 할 수 있습니다.
그리고 2번째 인자는 accumulator의 최초 값을 의미하며 미 정의시 호출된 배열의 첫 번째 요소로 설정됩니다.
가장 간단히 배열의 모든 요소를 더한 값을 구한다고 할 때, for 대신 reduce를 이용하면 조금은 코드의 단순화를 꾀할 수 있습니다.
'누적한 값을 인자로 받는다' 라는 특성을 다르게 해석하면
이전 loop의 값을 가져온다
라고 볼 수 있습니다.
즉, reduce는 async/await를 이용해 비동기 동작을 순차실행시킬 수 있습니다.
const API_LIST=[...]
async function apiSynchronize() {
await API_LIST.reduce(async (promise,url)=>{
let promiseResult = await promise;
promiseResult = await doAxios({url:url})
return promiseResult;
},{})
}
또는 Promise chaining을 사용할 수 있습니다.
const API_LIST=[...]
async function apiSynchronize() {
await API_LIST.reduce((promise,url)=>{
return promise.then(()=>{
doAxios({url:url})
})
},Promise.resolve())
}
덧붙여 클래식하게, for문도 사용할 수 있긴 합니다.
const API_LIST=[...]
async function apiSynchronize(){
for (const apis of API_LIST){
await doAxios({url:apis});
}
}
기준이 되는 api는 위와 같습니다.
친숙한 dog api를 사용했습니다.
api가 선언된 순서와 다르게 나옵니다.
반면, 이 경우 선언된 순서에 맞게 나옵니다.
순차실행의 장점은 모든 비동기 동작이 완료되어야 그 다음 동작을 발생시킬 수 있다는 점에 있습니다. 로딩 중인지? 모두 로딩 되었는지? 에 대한 것들을 제어하기 쉽습니다.
비동기 실행의 장점은 동작이 병렬적으로 수행되기에 완료 시점이 빠릅니다. 다만 로딩 상태에 대해서는 별도의 처리가 필요합니다.
모든 데이터를 받은 뒤, 전부 완료되면 컨텐츠를 렌더링하는 것의 구현이 필요했습니다.
1. 응답이 발생하면 .then() 체이닝으로 몇 개의 통신이 완료되었는지 처리 2. reduce 자체에 .then() 체이닝으로 로딩 완료 또는 에러 발생 처리 3. 로딩 중일 때 검색 버튼을 누르면 alert 표시 4. 로딩 완료시 컨텐츠 렌더링