원본 코드
- app.listen()의 두 번째 인자인 콜백 함수는 실제로 비동기로 동작하여, runServer()의 호출 이후 독립된 흐름으로 실행된다.
export function runServer(app: Koa) {
app.listen(serverConfig.port, () => {
// .. Do Something Here
});
}
목표
- 독립적인 Promise 활용
- Promise 생성자 콜백 내부에서 로직을 처리하지 않고, resolve를 끄집어내어 독립적으로 사용
- runServer 함수를 async로 변환
- 콜백의 실행이 완전히 종료되어야 runServer() 함수가 종료되도록 강제 흐름 제어
수정 코드
- 미리 Promise의 resolve 콜백을 담아둘
releaseLock
변수를 준비한다.
lockHandle
(Promise) 변수가 생성될 때, Promise의 생성자가 실행되며 releaseLock 변수에 resolve 핸들을 초기화한다.
- app.listen 콜백 바디 끝부분에
releaseLock()
을 호출하여, Promise의 대기를 종료하게 한다.
- runServer의 바디 끝부분에
lockHandle
을 대기함으로써, 직선 흐름 제어가 완성된다.
export async function runServer(app: Koa) {
let releaseLock = () => {};
const lockHandle = new Promise((resolve) => {
releaseLock = () => { resolve(null); };
});
app.listen(serverConfig.port, () => {
// .. Do Something Here
releaseLock();
});
await lockHandle;
}
상세(실행 순서 표시)
export async function runServer(app: Koa) {
let releaseLock = () => {};
// => [1]
const lockHandle = new Promise((resolve) => {
// => [2]
releaseLock = () => {
// => [6]
resolve(null);
};
});
// => [3]
app.listen(serverConfig.port, () => {
// => [5]
releaseLock();
});
// => [4]
await lockHandle;
// => [7]
}