class UserStorage{
loginUser(id, pw, onSuccess, onError){
setTimeout(()=>{
if(
(id ==='ellie' && pw === '1234') ||
(id === 'coder' && pw === '12345')
){
onSuccess(id);
}else{
onError(new Error(" not found!!!0"))
}
}, 2000);
}
getRole(user, onSuccess, onError){
setTimeout(()=> {
if(user==='ellie'){
onSuccess({name: 'ellie', role: 'admin'});
}else{
onError(new Error('no acceess'));
}
}, 1000);
}
}
const storage = new UserStorage();
storage.loginUser("ellie", "1234", (id)=>{
storage.getRole(id, (user)=> console.log(user.name +" "+ user.role),()=> console.log("엥 에러남") )
문제점
1. 가독성 ↓
2. 유지보수 힘듦
-> 비동기 코드를 효율적으로 작성해보자 -> promise 활용
콜백함수를 쓰지 않고, promise를 활용해서 비동기코드를 깔끔하게 처리해보자
const promise = new Promise((resolve, reject) => {
//heavy한 비동기적인 일 수행
console.log("doing something...");
setTiemout(()=> {
resolve('ellie');
}, 2000);
})
//정상적으로 수행이 된다면 어떠한 value를 받아올 것이다
//resolve에서 넘겨준 'ellie'가 value에 들어올 것이다
//then과 catch는 promise를 반환하기 때문에 체이닝이 가능
promise.then((value) =>{
console.log(value);
}).catch(error -> {
console.log(error);
}).finally(()=>{
console.log("finally");
});
const getHen = () =>
new Promise((resolve, reject) => {
setTimeout(() => resolve('🐓'), 1000);
});
const getEgg = hen =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(`${hen} => 🥚`), 1000);
//setTimeout(() => reject(new Error('달걀없슴'), 1000);
});
const cook = egg =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(`${egg} => 🍳`), 1000);
});
getHen() //
.then(getEgg)
.catch(error => {
return '🍔';//만약에 error가 났을 시에는 빵을 대신 전달해준다
})
.then(cook)
.then(console.log)
.catch(console.log);
promise는 비동기 작업의 단위 이다
callback함수는 인자로 함수를 받는 함수이다
let promise = new Promise(function(resolve, reject) {
// executor 부분
});
executor는 보통 시간이 걸리는 일을 수행합니다. 일이 끝나면 resolve나 reject 함수를 호출하는데, 이때 프라미스 객체의 상태가 변화합니다.
promise 생성자는 함수를 인자로 받습니다. 이 함수를 executor 라는 이름으로 부릅니다.
Promise 의 특징은 new Promise(...) 하는 순간 여기에 할당된 비동기 작업은 바로 시작됩니다. 비동기 작업의 특징은 작업이 언제 끝날지 모르기 때문에 일단 배를 떠나보낸다고 이야기했습니다. 그럼 그 이후에 이 작업이 성공하거나 실패하는 순간에 우리가 또 뒷처리를 해줘야겠죠? Promise 가 끝나고 난 다음의 동작을 우리가 설정해줄 수 있는데, 그것이 바로 then 메소드와 catch 메소드입니다.
then 메소드는 해당 Promise 가 성공했을 때의 동작을 지정합니다. 인자로 함수를 받습니다.
catch 메소드는 해당 Promise 가 실패했을 때의 동작을 지정합니다. 인자로 함수를 받습니다.
1초 뒤에 promise1,2 의 age에 따라 실행결과를 출력하는 메서드를 구현해보세요
function startAsync(age) {
return new Promise((resolve, reject) => {
if (age > 20) resolve();
else reject();
});
}
setTimeout(() => {
const promise1 = startAsync(25);
promise1
.then(() => {
console.log("1 then!");
})
.catch(() => {
console.log("1 catch!");
});
const promise2 = startAsync(15);
promise2
.then(() => {
console.log("2 then!");
})
.catch(() => {
console.log("2 catch!");
});
}, 1000);
function startAsync(age) {
return new Promise((resolve, reject) => {
if (age > 20) resolve();
else reject();
});
}
async function startAsync(age) {
if (age > 20) return `${age} success`;
else throw new Error(`${age} is not over 20`);
}
let promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve("완료!"), 1000);
});
// resolve 함수는 .then의 첫 번째 함수(인수)를 실행합니다.
promise.then(
result => alert(result), // 1초 후 "완료!"를 출력
error => alert(error) // 실행되지 않음
);
.then의 첫 번째 인수는 프라미스가 이행되었을 때 실행되는 함수이고, 여기서 실행 결과를 받습니다.
.then의 두 번째 인수는 프라미스가 거부되었을 때 실행되는 함수이고, 여기서 에러를 받습니다.
첫번째 줄에서 resolve가 아니라 reject결과가 나왔다면 error를 출력했겠지
setTimeOut(callback함수(), 초)callback을 사용하면 비동기 로직의 결과값을 처리하기 위해서는 callback안에서만 처리를 해야하고, 콜백 밖에서는 비동기에서 온 값을 알 수가 없습니다. 하지만 promise를 사용하면 비동기에서 온 값이 promise 객체에 저장되기 때문에 코드 작성이 용이해집니다.
return value를 이용할 수 있다는 점
error handling이 동기식 코드와 유사하게 쓰일 수 있다는 점
const getHen = () => new Promise((resolve, reject) => {
console.log("안녕ssssss");
setTimeout(() => {
console.log("안녕");
resolve('❤');
}, 1000);
})
let promise = new Promise(function(resolve, reject) {
// executor 부분
});
function getData() {
var tableData;
$.get('https://domain.com/products/1', function(response) {
tableData = response;
});
return tableData;
}
console.log(getData()); // undefined
앞서 말한 js 비동기처리방식의 문제를 해결하였다
function getData(callbackFunc) {
$.get('https://domain.com/products/1', function(response) {
callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
});
}
getData(function(tableData) {
console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});
$.get('url', function(response) {
parseValue(response, function(id) {
auth(id, function(result) {
display(result, function(text) {
console.log(text);
});
});
});
});
function parseValueDone(id) {
auth(id, authDone);
}
function authDone(result) {
display(result, displayDone);
}
function displayDone(text) {
console.log(text);
}
$.get('url', function(response) {
parseValue(response, parseValueDone);
});
출처
https://ko.javascript.info/promise-basics#ref-700
https://elvanov.com/2597
https://jcon.tistory.com/189
https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/