동기: synchronous
현재 실행중인 코드가 끝나야 다음 코드가 실행되는 방식
CPU에 계산에 의해 즉시 처리가 가능한 대부분의 코드.
비동기: a + synchronous => async 라고 흔히 부른다.
실행중인 코드의 완료 여부와 무관하게 다음 코드가 실행되는 방식
주로 요청, 실행대기, 보류 등과 관련된 코드
setTimeout(function(){
console.log('1번')
}, 1000)
console.log('2번') // 2번이 먼저 실행된다.
1번 코드가 먼저 실행돼야 하는 작업이라면 어떻게 해야할까?
setTimeout(function () {
console.log("1번");
setTimeout(function () {
console.log("2번");
}, 1000);
}, 1000);
이런 식의 작업이 3번... 4번... 계속 반복된다면 코드가 점점 복잡해지고
가독성이 떨어질 것이다.
아래 코드는 커피의 목록이 순차적으로 추가되는 함수.
setTimeout(
function (name) {
var coffeeList = name;
console.log(coffeeList);
setTimeout(
function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(
function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(
function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
},
500,
"카페라떼"
);
},
500,
"카페모카"
);
},
500,
"아메리카노"
);
},
500,
"에스프레소"
); // 해석하기 어렵고 가독성이 떨어진다.
이러한 코드가 작성되는 이유는 코드가 순서대로 진행이 되어야 하기 때문이다.예를 들어
1번 코드가 실행되고 2번 코드가 실행되어야 한다.
만약에 서버 문제로 1번 코드가 지연이 되고 2번 코드가 먼저 실행되면
오류가 발생하게 된다.
1번 코드가 실행이 되어야만 2번 코드가 실행되게 수정할 필요가 있다
Promise는 비동기 처리에 대해, 처리가 끝나면 알려달라는 ‘약속’
new 연산자로 호출한 Promise의 인자로 넘어가는 콜백은 바로 실행된다.
그 내부의 resolve(또는 reject) 함수를 호출하는 구문이 있을 경우
resolve(또는 reject) 둘 중 하나가 실행되기 전까지는 다음(then), 오류(catch)로 넘어가지 않는다
따라서, 비동기작업이 완료될 때 비로소 resolve, reject 호출한다.
커피 목록이 순차적으로 추가되는 함수를 Promise를 사용해 바꿔보자
new Promise(function (resolve) {
setTimeout(function () {
var name = "에스프레소";
console.log(name);
resolve(name);
}, 500);
})
.then(function (prevName) {
return new Promise(function (resolve) {
setTimeout(function () {
var name = prevName + ", 아메리카노";
console.log(name);
resolve(name);
}, 500);
});
})
.then(function (prevName) {
return new Promise(function (resolve) {
setTimeout(function () {
var name = prevName + ", 카페모카";
console.log(name);
resolve(name);
}, 500);
});
})
.then(function (prevName) {
return new Promise(function (resolve) {
setTimeout(function () {
var name = prevName + ", 카페라떼";
console.log(name);
resolve(name);
}, 500);
});
});
반복되는 부분을 리펙토링 해주면
var addCoffee = function (name) {
return function (prevName) {
return new Promise(function (resolve) {
setTimeout(function () {
var newName = prevName ? `${prevName}, ${name}` : name;
console.log(newName);
resolve(newName);
}, 500);
});
};
};
addCoffee("에스프레소")()
.then(addCoffee("아메리카노"))
.then(addCoffee("카페모카"))
.then(addCoffee("카페라떼"));
콜백 함수를 반복해서 사용하지 않고도 동기적으로 표현이 가능하다!