콜백함수에 대한 개념은 여기를 참고한다.
Promise에 대한 참고자료
비동기적으로 작업을 실행하기 위해 콜백함수를 활용하게 된다.
function firstFunc(a,b, inFunc) {
setTimeout(() => {
const result = a +b;
inFunc(result);
}, 2000);
}
firstFunc(5,5, (res) => console.log(res));
console.log("end");
하지만 이런 함수가 계속해서 중첩하게 된다면?
가독성이 최악인 코드가 생겨날 것이다.
function increase(number, callback) {
setTimeout(() => {
const result = number + 10;
if (callback){
callback(result);
}
},1000)
}
increase(0, result => {
console.log(result);
increase(result, result => {
console.log(result);
increase(result, result => {
console.log(result);
console.log("작업 완료");
});
});
});
console.log("과연 마지막에 호출될까?");
이를 해결하기위해 Promise
가 등장한다.
let promise = new Promise(function(resolve, reject) {
// executor (제작 코드, '가수')
});
resolve와 reject 두가지 경우가 있다. 이는 자바스크립트가 제공하는 콜백함수이다. (따라서 개발자는 excutor만 작성하면 된다.)
둘 중 하나의 콜백함수는 무조건! 호출해야한다.
위에서 언급되는 promise객체 내부의 state
, result
는 직접 접근할 수 없다. .then, .catch, .finally
메서드들을 통해서만 접근 가능하다.
.then(성공시 f, 실패시 f)
.then(f)
이와 같이 사용한다..catch(f)
.finally(f).then(f)
.finally(f).catch(f)
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000); // (*)
}).then(function(result) { // (**)
alert(result); // 1
return result * 2;
}).then(function(result) { // (***)
alert(result); // 2
return result * 2;
}).then(function(result) {
alert(result); // 4
return result * 2;
});
let promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000);
});
promise.then(function(result) {
alert(result); // 1
return result * 2;
});
promise.then(function(result) {
alert(result); // 1
return result * 2;
});
promise.then(function(result) {
alert(result); // 1
return result * 2;
});
function promisify(f) {
return function (...args) { // 래퍼 함수를 반환함
return new Promise((resolve, reject) => {
function callback(err, result) { // f에 사용할 커스텀 콜백** = 헬퍼함수 느낌
if (err) {
reject(err);
} else {
resolve(result);
}
}
args.push(callback); // 위에서 만든 커스텀 콜백을 함수 f의 인수 끝에 추가합니다.
// 이렇게 추가하고 아래에서 진짜 실행
f.call(this, ...args); // 기존 함수를 호출합니다. = 진짜 실행되는 부분!!!
});
};
};
// 사용법:
let loadScriptPromise = promisify(loadScript);
loadScriptPromise(...).then(...);
함수 앞에 붙이는 키워드. 아래 두가지 기능을 갖는다.
1. 항상 promise를 반환한다.
2. 함수 내에서 await을 사용할 수 있다.
함수 내에서 await 키워드를 사용한다면, 해당 프라미스가 완료되기까지 함수의 실행을 잠심 멈춘다.
또한 await은 thenable한 객체를 return한다.
!주의!
최상위 코드에서 async/await을 사용할 수 없다.
그래서 이럴 땐 익명함수로 감싸서 사용해야한다.(async () => { let response = await fetch('/article/promise-chaining/user.json'); let user = await response.json(); ... })();