November 17, 2021
콜백을 받는 함수를 프라미스를 반환하는 함수로 바꾸는 것을 '프라미스화(promisification)'라고 합니다.
콜백보다는 프라미스가 더 편리하기 때문에, 구현을 하다 보면 콜백 기반 함수와 라이브러리를 프라미스를 반환하는 함수로 바꾸는 게 좋은 경우가 종종 생길 겁니다.
콜백 챕터에서 사용했던 loadScript(src, callback)
예시를 사용해 프라미스화에 대해 좀 더 자세히 알아봅시다.
loadScript(src, callback)
를 이제 프라미스화해봅시다. 새로운 함수 loadScriptPromise(src)
는 loadScript
와 동일하게 동작하지만 callback
을 제외한 src
만 인수로 받아야 하고, 프라미스를 반환해야 합니다.
let loadScriptPromise = function(src) {
return new Promise((resolve, reject) => {
loadScript(src, (err, script) => {
if (err) reject(err)
else resolve(script);
});
})
}
// 사용법:
// loadScriptPromise('path/script.js').then(...)
새롭게 구현한 loadScriptPromise
는 프라미스 기반 코드와 잘 융화됩니다.
예시에서 볼 수 있듯이, loadScriptPromise
는 기존 함수 loadScript
에 모든 일을 위임합니다. loadScript
의 콜백은 스크립트 로딩 상태에 따라 이행
혹은 거부
상태의 프라미스를 반환합니다.
그런데 실무에선 함수 하나가 아닌 여러 개의 함수를 프라미스화 해야 할 겁니다. 헬퍼 함수를 만드는 게 좋을 것 같네요. 프라미스화를 적용 할 함수 f
를 받고 래퍼 함수를 반환하는 함수 promisify(f)
를 만들어봅시다.
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(...);