안녕하세요
이번 포스팅에서는 자바스크립트의 콜백함수(Callback)패턴에 대해 알아보도록 하겠습니다!
콜백함수를 쓰는이유? 중 대표적인것은
"비동기" 처리를 위해서인데요
콜백함수 뿐만 아니라 프라미스(Promise), Async/Await(비동기함수)도 씁니다.
이번 포스팅은 콜백함수에 대해 알아보도록 하겠습니다!
[예제는 Node.js 환경에서 테스트할 예정이구요 Node.js 뿐만 아니라 웹 브라우저에서 사용하셔도 동일합니다!]
자바스크립트의 변수에는 숫자, 문자, 객체 등등을 담을 수 있습니다.
심지어 함수까지 저장이 가능합니다.
함수는 자바스크립트에서 일급 객체입니다.
https://ko.wikipedia.org/wiki/%EC%9D%BC%EA%B8%89_%EA%B0%9D%EC%B2%B4
일급 객체는 아래의 조건을 충족해야 합니다.
- 변수나 데이터 구조안에 담을 수 있다.
- 함수의 인자로 전달 할 수 있다.
- 반환값으로 사용할 수 있다.
자바스크립트에서 함수는 위의 조건을 모두 충족합니다.
위 사진은 함수를 변수 f에 할당한 모습입니다.
f에는 함수가 들어있고 아래에서 f() 를 통해 함수를 호출하고 있죠
이처럼 자바스크립트에서는 함수를 변수에 담을 수 있고 다른 함수의 인자로 전달도 가능합니다.
위 코드의 실행 결과는 7이 출력될 것 입니다.
아래 사진은 콜백함수의 간단한 예제입니다.
test라는 함수는 인자로 함수를 받습니다.
아래 6행을 보시면 test 함수를 호출하면서 새로운 함수를 전달하고 있습니다.
전달된 함수는 test 함수의 매개변수 f에 저장이 될 것이고
2행에서 f()를 호출하고 있습니다.
호출한 결과는 당연히 전달한 함수 내의 코드가 실행되겠죠.
결과는 위와 같습니다.
또 다른 예제를 확인해봅시다.
loading 이라는 변수에 함수가 저장되어있습니다.
해당 함수는 path, done이라는 매개변수를 받는데요
path에는 문자열
done에는 함수를 전달 받습니다.
(자바스크립트의 단점 중 하나가 타입의 구분이 없습니다. path, done만 보고 해당 변수가
어떤 자료형을 저장하는지 쉽게 알 수 없기 때문에 주석으로 남겨두거나 타입스크립트를 사용합니다)
6행에서 loading 함수를 호출하며 path의 인자로 '/folder/text'를 전달하고
두 번째 done의 인자로는 함수를 전달하고 있습니다.
콜백함수는 위에서 아래로 흐른다고 생각하면 헷갈릴 수 있기 때문에 함수가 호출되고 어떻게 흘러가는지 천천히 분석하셔야 합니다.
먼저 1행에서 함수를 구현만 해두고 6행에서 실제로 호출이 됩니다.
(1)
path로 넘어간 데이터가 2행에서 출력
(2)
콜백함수인 done을 호출하며 기존의 path에 'sample.txt' 문자열을 이어서 전달
(3)
전달된 문자열이 7행에서 출력이 됨
위 코드의 실행결과는 아래와 같습니다.
콜백함수를 사용하는 이유는 주로 비동기 작업 때문입니다.
위 코드에 빗대어 설명하자면
어떤 작업을 진행시켜두고(loading 함수 호출 및 데이터, 콜백함수 전달)
loading 함수 내에서 작업을 처리합니다. (path 출력, path + 'sample.txt' 연산)
완료 되었을 때 전달받은 콜백함수(done) 호출
콜백함수에서는 결과를 받고 작업 이후의 기능을 처리합니다.
DB 작업, 데이터 입출력 등 시간이 꽤 걸리는 작업을 순차적으로 진행해야 하는데 만약 해당 기능이 비동기로 구현되어있다면
각각의 기능이 거의 동시에 실행되고 어떤 작업을 빨리 끝나고 어떤 작업은 늦게 끝나고 등등 순서에 문제가 발생할 수 있습니다.
콜백함수 패턴을 사용하면
1작업을 시켜두고 작업이 완료되었을 때 알림을 받을 콜백함수를 같이 줍니다.
1작업이 완료되면 콜백함수가 호출이 될것이고 해당 콜백함수 안에서 작업2를 시작하게 되면
1작업 완료 후 > 2작업 시작
즉, 비동기 작업들을 순차적으로 실행이 가능합니다.
콜백함수도 좋긴 하지만 콜백함수가 너무 많이 중첩이 되면 가독성이 크게 떨어집니다.
아래와 같이 말이죠..
출처: https://medium.com/ninjadevs/node-7-6-koa-2-asynchronous-flow-control-made-right-b0d41c6ba570
이러한 문제를 해결하기 위해 나타난 방법이 Promise 패턴입니다!
다음 포스팅에서는 Promise 에 대해 알아보도록 하겠습니다.
감사합니다.