Callback 문제
const fs = require("fs");
const getDataFromFile = function (filePath, callback) {
// TODO: fs.readFile을 이용해 작성합니다
fs.readFile(filePath,'utf-8',(err,data) => {
if (err){
callback(err,null);
}else{
callback(null,data);
}
});
};
/*
if(err){
callback(err,null);
*test내용 : 에러가 발생할 경우, callback 첫번째 인자에 에러 객체가 전달되어야 한다.
}else{
callback(null,data)
*test 내용 : callback 두번째 인자에 파일 내용이 전달되어야 한다.
}
*/
- fs.readFile()에 관하여,
Node.js가 '파일을 읽는' 방법.const fs = require('fs') //"Node.js 의 파일 읽기 '모듈'을 활용하겠다." 라고 선언 fs.readFile(path[,options],callback) /* path : <string>|<Buffer>|<URL>|<integer> - path에는 파일 이름을 인자로 넘기는데, 위와 같이 네 가지 타입이 있다. 보통 문자열로 넘긴다. options : <Object>|<string> -encoding, flag를 넣어줄 수 있다. -optional한 인자로 넣지 않을 수도 있다. 객체 또는 문자열 형대로 넘길 수 있다. -기본값은 'utf8' 이다. 보통은 생략하지 않고 적어주는 편이 좋다. callback : 파일을 읽은 후 호출되는 콜백 함수이다. - err : 작업에 실패하면 반환되는 오류 - data : 파일의 내용 */
사용 방법
const fs = require('fs')
fs.readFile('example.txt','utf8',(err,data)=>{
if(err){
/*
만약 파일을 읽어오는데 실패했다면?
아래는 에러 예시
* [Error: ENOENT: no such file or directory, open 'example1.txt'] {
* errno: -2,
* code: 'ENOENT',
* syscall: 'open',
* path: 'example1.txt'
*/
}else{
console.log(data);
}
}
JS에서 함수는
object
라고 한다. 함수는 다른 함수의 인자로 쓰일 수도 어떤 함수에 의해 리턴 될 수도 있다. 이런 함수를고차 함수
라고 한다. 결국, 인자로 넘겨지는 함수를콜백 함수
라고 한다. 또한, 단지 함수를 등록하기만 하고 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수.
function func(callback) {
callback();
}
function callback(){
console.log("callback이다.")
}
func(callback);
//result = callback이다.
위 예제는 callback 함수의 기본 형태. 함수 func(callback)을 호출했을 때, 밑에 있는 특정 callback함수가 실행된다. 제어권은 func(callback)에게 있다.
function introduce (lastName, firstName, callback) {
let fullName = lastName + firstName;
callback(fullName);
}
introduce("홍", "길동", function(name) {
console.log(name);
};
// 결과 -> 홍길동
출처: https://inpa.tistory.com/entry/JS-📚-자바스크립트-콜백-함수 [👨💻 Dev Scroll]
introduce 함수를 실행하면, callback자리를 새로운 함수 function(name)으로 지정 해주면서 함수 안에서 callback(fullname)으로 실행되는 함수가 된다.
콜백 함수를 설명할 때는 변수의 유효범위
scope
에 대한 이야기, 동기/비동기synchronous/Asynchronous
처리에 대한 이야기도 하면 좋을 것 같다.
- 동기: 하나의 요청이 오면 완료가 된 후 다음 요청을 실행하는 방식 - 순차적 로직 흐름
- 비동기: 어떤 요청이 오면 완료가 되기 전에 다음 요청을 실행하는 방식
-동시 효율적 처리 가능, 즉시 응답X 때문에 예상 밖 결과가 나올 수도 있다.
- 콜백함수는 때로는 가독성이나 코드 재사용 면에서도 사용된다.
- 비동기 방식으로 작성된 함수를 동기 처리하기 위해 필요하다.
function findUserAndCallback(id,cb){
const user = {
id: id,
name: "User" + id,
email: id + "@test.com"
};
cb(user);
}
//밑에 함수가 10번째 줄 함수
findUserAndCallBack(1, function(user){
console.log("user:",user);
});
10번째 줄 function의 인자로 id와 콜백 함수를 선언하여 호출하였다. 그래서 7번째 쭐의 cb 매개변수는 10번째 function 익명 함수를 콜백 함수로 할당 받으며, cb(user);가 실행될 때 이 콜백함수는 실행되게 된다. => 콜백 함수를 넣음에 따라 함수 내부에서 수행해주기 때문에 결과값을 return 할 필요가 없다.
function findUser(id) {
let user;
setTimeout(function () {
console.log("waited 0.1 sec.");
user = {
id: id,
name: "User" + id,
email: id + "@test.com",
};
}, 100);
return user;
}
const user = findUser(1);
console.log("user:", user);
결과
user: undefined
waited 0.1 sec.
위 예제는 setTimeout 같은 비동기 함수를 썼을 때의 예제이다. setTime()은 비동기 함수의 호출이기 때문에 실행 완료를 기다리지 않고 다음 라인인 11번째 줄로 넘어가 버린다. 즉, user객체는 무시하고 넘어가 버린다. finUser(1)은 Undefined가 할당된다. 그러고나서, 0.1초 후에 setTimeout() 함수의 첫번째 인자로 넘어간 콜백 함수가 실행되면서 waited 0.1 sec. 가 출력되고 user 로컬 변수에 원하는 객체가 할당되었지만 이미 무시 된 후이다.
function findUserAndCallBack(id, cb) {
setTimeout(function () {
console.log("waited 0.1 sec.");
const user = {
id: id,
name: "User" + id,
email: id + "@test.com",
};
cb(user);
}, 100);
}
findUserAndCallBack(1, function (user) {
console.log("user:", user);
});
결과
waited 0.1 sec.
user: {id: 1, name: "User1", email: "1@test.com"}
위에 예제는 결과값을 바로 리턴받지 않고, 그 결과값을 통해 처리할 로직을 콜백 함수로 넘겨서 제대로 구현을 하였다.
원문>
https://velog.io/@ko1586/Callback%ED%95%A8%EC%88%98%EB%9E%80-%EB%AD%94%EB%8D%B0