Callback과 Promise

2022. 11. 23. 21:22WEB개발/TIL

반응형

Callback(콜백)

: 함수가 끝난 뒤 실행되는 함수

  • 함수를 만들 때 paramater로 함수를 받아서 사용

 

 

Callback함수 사용하기

Callback함수를 사용하지 않은 코드

function func1() {
    console.log("첫 번째 출력");
    setTimeout (function() {
        console.log("두 번째 출력");
    },2000);
}
function func2() {
    console.log("세 번째 출력");
}
func1();
func2();//
// 결과
첫 번째 출력
세 번째 출력
두 번째 출력
  • setTimeout함수는 비동기 방식 → 콜백함수 사용

Callback함수를 사용한 코드

function func1(print,cb) {
    console.log("첫 번째",print);
    setTimeout (function() {
        console.log("두 번째",print);
        cb(print);
    },2000);
}
function func2(print) {
    console.log("세 번째",print);
}

func1("출력",function(print) {
    func2(print);
})
// 결과
첫 번째 출력
두 번째 출력
세 번째 출력

 

Callback함수를 사용하는 이유?

: 비동기 방식으로 작성된 함수를 동기 처리 하기 위해 사용

 

 

 

Callback Hell(콜백 지옥)

: 함수의 매개변수로 넘겨지는 콜백 함수가 반복되어, 코드의 들여쓰기가 너무 깊어지는 현상

  • 가독성이 낮음(=코드 수정 난이도 높음)
function login(id,cb) {
    console.log("사용자 입장");
    setTimeout(function() {
        console.log(id,"님 로그인 성공!");
        cb(id,);
    },1500);
}
function listloading(id,cb) {
    setTimeout(function() {
        console.log(id,"님의 music playlist");
        var mlist = ["antifragile","better","best part"];
        console.log(mlist);
        cb(mlist);
    },1500);
}
function select(mlist,cb) {
    setTimeout(function() {
        console.log('"',mlist[2],'" 노래 선택!');
        cb(mlist[2]);
    },1500);
}
function play(play) {
    setTimeout(function() {
        console.log('"',play,'" 노래 재생 시작♪');
    },1500);
}



login('nana',function(user) {
    listloading(user,function(list) {
        select(list,function(choose) {
            play(choose);
        })
    })
})
// 결과
사용자 입장
nana 님 로그인 성공!
nana 님의 music playlist
[ 'antifragile', 'better', 'best part' ]
" best part " 노래 선택!
" best part " 노래 재생 시작♪

 

 

 

 

 

Promise(프로미스)

: callbackhell로 인한 복잡도 증가와 예외처리의 어려움을 해결하기 위해 만들어진 것

  • 비동기작업에서 성공과 실패를 분리해 메소드를 수행
  • resolve(value): 일이 성공적으로 끝난 경우
    • promise를 실행한 곳의 then으로 들어감
  • reject(error): 에러가 발생한 경우(일이 성공적으로 끝나지 않은 경우)
    • promise를 실행한 곳의 catch로 들어감

 

Promise 기본 문법

new Promise(function(resolve, reject){
   // resolve: 함수형태, 성공했을 때 실행
   // reiect: 함수형태, 실패 혹은 에러 처리를 할 때 사용
});

 

Promise 사용하기

 Case1)

function func1() {
    return new Promise(function(resolve,reject) {
        resolve("성공!");
    });
}

console.log(func1());  // Promise { '성공!' }
func1().then(function(result) {
    console.log(result); // 성공!; then은 promise의 값을 리턴함
})

Case2)

function func2() {
    return new Promise(function(resolve,reject) {
        setTimeout(function() {
            resolve("성공!!");
        },2000);
    });
}
console.log(func2());  // Promise { <pending> }
func2().then(function(result) {
    console.log(result); // 성공!!; 2초 후에 출력됨
})
  • setTimeout함수는 비동기이기 때문에 pending상태로 출력됨
  • fulfilled상태가 되면 then함수 실행됨(2초 후 “성공!!”출력)

      → 비동기를 동기처럼 사용할 수 있게함.

 

 

Promise의 상태

  • pending: promise를 수행 중인 상태
  • fulfilled: promise가 resolve된 상태
  • rejected: promise가 지켜지지 못한 상태
  • settled: fulfilled 혹은 rejected로 결론이 난 상태

 

 

.then()과 .catch()

Case1) 첫 번째 콜백 함수(reslove)가 true일 경우, 첫 번째 함수 동작

Case2) 두 번째 콜백 함수(reject)가 true일 경우, 두 번째 함수 동작

Case3) then함수에 동작해야 할(조건에 충족한) 함수가 없을 경우, catch함수 동작

  • then함수가 먼저 처리할 경우, catch함수는 동작하지 않음
function func4(nana) {
    return new Promise(function(resolve,reject){
        if (nana) {
            resolve("nana는 true");
        } else {
            reject("nana는 false");
        }
    });
}
// case1
func4(true)
    .then(function(nana) {
        console.log(nana);
    }, function(nana) {
        console.log(nana);
    });

// case2
func4(false)
    .then(function(nana) {
        console.log(nana);
    }, function(nana) {
        console.log(nana);
    });

// case3
func4(false)
    .then(function(nana) {
        console.log(nana);
    })
    .catch(function(nana) {
        console.log(nana);
    });//ruf
// 결과
nana는 true
nana는 false
nana는 false

 

Chaining(체이닝)

: 코드를 더 효율적으로 작성하기 위해 사용

  • callbackhell에 비해 가독성이 높으며, 코드 수정을 쉽게 할 수 있음
function func3() {
    return new Promise(function(resolve, reject) {
        resolve("hello");
    })
}
func3()
    .then(function(hello) {
        console.log(hello);
        return "hi";
    })
    .then(function(hi){
        console.log(hi);
    });
// 결과
hello
hi

 

 

 

Callbackhell에서 작성했던 코드 Promise로 작성해보기

function login(id) {
    return new Promise(function(resolve,reject) {
        console.log("사용자 입장");
        setTimeout(function() {
            console.log(id,"님 로그인 성공!");
            resolve(id);
        },1500);
    });
}
function listloading(id) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log(id,"님의 music playlist");
            var mlist = ["antifragile","better","best part"];
            console.log(mlist);
            resolve(mlist);
        },1500);
    });
}
function select(mlist) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log('"',mlist[2],'" 노래 선택!');
            resolve(mlist[2]);
        },1500);
    });
}
function play(play) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log('"',play,'" 노래 재생 시작♪');
        },1500);
    });
}



login('nana')
    .then(function(user) {
        return listloading(user);
    })
    .then(function(list) {
        return select(list);
    })
    .then(function(choose) {
        return play(choose);
    });
// 결과
사용자 입장
nana 님 로그인 성공!
nana 님의 music playlist
[ 'antifragile', 'better', 'best part' ]
" best part " 노래 선택!
" best part " 노래 재생 시작♪

 

 

 

 

 

반응형

'WEB개발 > TIL' 카테고리의 다른 글

http모듈  (0) 2022.11.23
fs모듈(FileSystem Module)  (0) 2022.11.23
Class, Object, Instance  (0) 2022.11.21
구조분해 할당(Destructuring assignment)  (0) 2022.11.21
Node.js(module)  (0) 2022.11.21