예제
const NAME = "Invidam",
ID = { Invidam: 123 },
INFO = { 123: { age: 23, hobby: ["game", "study", "movie"] } };
const findIdByNameInDB = (name) =>
new Promise((resolve, _) =>
setTimeout(() => {
resolve(ID[name]);
}, 1000)
);
const findInfoByIdInDB = (id) =>
new Promise((resolve, _) =>
setTimeout(() => {
resolve(INFO[id]);
}, 1000)
);
const getIdByName = async (name) => {
let ret = await findIdByNameInDB(name);
console.log(`GET ID BY NAME, NAME: ${name} -> ID: ${ret}`);
return ret;
};
const getInfoById = async (id) => {
let ret = await findInfoByIdInDB(id);
console.log(
`GET INFO BY ID, ID: ${id} -> INFO: ${JSON.stringify(ret, null, 2)}`
);
return ret;
};
결과값
FINALLY, INFO: Promise { <pending> }
GET ID BY NAME, NAME: Invidam -> ID: 123
GET INFO BY ID, ID: [object Promise] -> INFO: undefined
가정
getIdByName
: 이름 -> ID를 가져오는 비동기 함수getInfoById
: ID -> 정보를 가져오는 비동기 함수printInfo
: 정보 출력하는 동기 함수일반적인 함수처리 방식을 사용 (printInfo(getInfoById(getIdByName(NAME)))
)
실행과정
getIdByName
이 비동기 함수이므로 태스크 큐로 들어간다.getInfoById
가 비동기 함수이므로 태스크 큐로 들어간다.printInfo
가 실행된다.Info
가 아직 결정되지 않았기에 반환을 해 줄 비동기 함수가 대기중이라는 표현 Promise { <pending> }
이 출력되며, 원하는 결과를 얻지 못한다.예제
const NAME = "Invidam",
ID = { Invidam: 123 },
INFO = { 123: { age: 23, hobby: ["game", "study", "movie"] } };
const findIdByNameInDB = (name) =>
new Promise((resolve, _) =>
setTimeout(() => {
resolve(ID[name]);
}, 1000)
);
const findInfoByIdInDB = (id) =>
new Promise((resolve, _) =>
setTimeout(() => {
resolve(INFO[id]);
}, 1000)
);
const getIdByName = async (name, callback) => {
let ret = await findIdByNameInDB(name);
console.log(`GET ID BY NAME, NAME: ${name} -> ID: ${ret}`);
callback(ret);
};
const getInfoById = async (id, callback) => {
let ret = await findInfoByIdInDB(id);
console.log(
`GET INFO BY ID, ID: ${id} -> INFO: ${JSON.stringify(ret, null, 2)}`
);
callback(ret);
};
const printInfo = (info) => console.log("FINALLY, INFO: ", info);
getIdByName(NAME, (id) => getInfoById(id, printInfo));
결과
GET ID BY NAME, NAME: Invidam -> ID: 123
GET INFO BY ID, ID: 123 -> INFO: {
"age": 23,
"hobby": [
"game",
"study",
"movie"
]
}
FINALLY, INFO: { age: 23, hobby: [ 'game', 'study', 'movie' ] }
정상적으로 원하는 결과가 출력되었다.
변경사항
return ret
이 사라지고 callback(ret)
으로 변경되었다.getIdByName(NAME, (id) => getInfoById(id, printInfo));
으로 실행하는 코드가 변경되었다.실행과정
getIdByName
가 비동기 함수이므로 태스크 큐에 들어간다.getIdByName
이 콜스택에 들어가며 실행된다.getInfoById
를 실행한다.getInfoById
가 비동기 함수이므로 태스크 큐에 들어간다.getInfoById
가 콜스택에 들어가며 실행된다.printInfo
를 실행한다.예제
const NAME = "Invidam",
ID = { Invidam: 123 },
INFO = { 123: { age: 23, hobby: ["game", "study", "movie"] } };
const findIdByNameInDB = (name) =>
new Promise((resolve, _) =>
setTimeout(() => {
resolve(ID[name]);
}, 1000)
);
const findInfoByIdInDB = (id) =>
new Promise((resolve, _) =>
setTimeout(() => {
resolve(INFO[id]);
}, 1000)
);
const promiseGetIdByName = (name) => {
return new Promise(async (resolve, reject) => {
let ret = await findIdByNameInDB(name);
console.log(`GET ID BY NAME, NAME: ${name} -> ID: ${ret}`);
resolve(ret);
});
};
const promiseGetInfoById = (id) => {
return new Promise(async (resolve, reject) => {
let ret = await findInfoByIdInDB(id);
console.log(
`GET INFO BY ID, ID: ${id} -> INFO: ${JSON.stringify(ret, null, 2)}`
);
console.log(JSON.stringify(id));
resolve(ret);
});
};
const printInfo = (info) => console.log("FINALLY, INFO: ", info);
promiseGetIdByName(NAME)
.then((name) => promiseGetInfoById(name))
.then((info) => printInfo(info))
.catch((err) => console.err(err));
결과값은 콜백 예제와 동일하다.
변경사항 (비교: 콜백 패턴)
return ret
이 사라지고 resolve(ret)
으로 변경되었다.promiseGetIdByName(NAME).then((name) => promiseGetInfoById(name)) .then((info) => printInfo(info)) .catch((err) => console.err(err))
으로 실행하는 코드가 변경되었다.실행과정
promiseGetIdByName
가 실행된다.promiseGetIdByName
가 resolve(ret)
이 실행되며 종료된다.promiseGetIdByName
의 프로미스 상태변화를 감지한 then()
의 callback인 promiseGetInfoById
가 호출되며 인자로 ret{id}을 전달받는다.resolve(ret)
으로 info가 전달된다.printInfo
를 실행한다. const NAME = "Invidam",
ID = { Invidam: 123 },
INFO = { 123: { age: 23, hobby: ["game", "study", "movie"] } };
const findIdByNameInDB = (name) =>
new Promise((resolve, _) =>
setTimeout(() => {
resolve(ID[name]);
}, 1000)
);
const findInfoByIdInDB = (id) =>
new Promise((resolve, _) =>
setTimeout(() => {
resolve(INFO[id]);
}, 1000)
);
const promiseGetIdByName = (name) => {
return new Promise(async (resolve, reject) => {
let ret = await findIdByNameInDB(name);
console.log(`GET ID BY NAME, NAME: ${name} -> ID: ${ret}`);
resolve(ret);
});
};
const promiseGetInfoById = (id) => {
return new Promise(async (resolve, reject) => {
let ret = await findInfoByIdInDB(id);
console.log(
`GET INFO BY ID, ID: ${id} -> INFO: ${JSON.stringify(ret, null, 2)}`
);
console.log(JSON.stringify(id));
resolve(ret);
});
};
const printInfo = (info) => console.log("FINALLY, INFO: ", info);
(async () => {
try {
const id = await promiseGetIdByName(NAME);
const info = await promiseGetInfoById(id);
printInfo(info);
} catch (error) {
console.error(err);
}
})();
결과값은 콜백 예제와 동일하다.
변경사항 (비교: 프로미스)
실행과정
promiseGetIdByName
가 실행되며, await 키워드가 이 함수를 기다린다.promiseGetIdByName
가 resolve(ret)
이 실행되며 종료된다.promiseGetIdByName
의 프로미스 상태변화를 await 키워드가 감지하여 ret이 id 변수에 할당된다.promiseGetInfoById
가 실행되며, await 키워드가 이 함수를 기다린다.promiseGetInfoById
가 resolve(ret)
이 실행되며 종료된다.promiseGetInfoById
의 프로미스 상태변화를 await 키워드가 감지하여 ret이 info 변수에 할당된다.printInfo
를 실행한다.