삶 가운데 남긴 기록 AACII.TISTORY.COM
javascript 비동기 처리 Promise 본문
비동기 처리
console.log("A");
setTimeout(function(){console.log("B");}, 0);
console.log("C");
위 코드의 실행 결과는 A -> C -> B 순으로 표시됩니다.
비동기 작업은 콜백 함수로 작업을 예약 해놓고 다음 작업을 수행하기 때문입니다.
콜백 지옥
function sleep(callback){
setTimeout(function(){
callback();
},1000);
}
sleep(function(){
console.log("A");
sleep(function(){
console.log("B");
sleep(function(){
console.log("C");
});
});
});
Promise
var promise = new Promise(function(resolve, reject){ ... });
resolve : 함수 처리가 완료된 후 호출해야 하는 콜백 함수
reject : 함수 처리가 실패한 후 호출해야 하는 콜백 함수
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> </title>
</head>
<body>
<script>
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
console.log("A");
resolve();
}, 1000);
});
promise.then(function(){
console.log("B");
});
</script>
</body>
</html>
1초후에 A가 표시되고 resolve()를 호출하여 비동기 처리를 종료시킵니다.
resolve()함수가 실행되면 then 메서드에 등록한 함수가 호출됩니다.
따라서 B가 표시됩니다.
promise.then(onFullfilled(response));
onFullfilled() 함수는 비동기 작업 성공시 실행하는 콜백함수입니다.
onFullfilled(response)의 response는 resolve()함수를 실행 할 때 넘긴 인수 입니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> </title>
</head>
<body>
<script>
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
var name = prompt("이름을 입력하십시오");
resolve(name);
}, 1000);
});
promise.then(function(name){
console.log("안녕하세요. " + name);
});
</script>
</body>
</html>
promise.catch(onRejected);
reject()함수도 마찬가지로 Promise를 종료시키면서 값을 넘길 수 있습니다.
reject()함수가 실행되면 then메서드에 넘긴 함수는 실행되지 않고 catch()메서드에 넘긴 함수가 실행됩니다.
onRejected()함수는 실패시 실행되는 콜백 함수이며 인수로 error를 받습니다.
이 error은 reject(error)을 실행 할 때 넘긴 인수 입니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> </title>
</head>
<body>
<script>
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
var n = parseInt(prompt("10 미만 숫자를 입력"));
if(n <= 10){
resolve(n);
}else{
reject(`오류: ${n}은 10 이상입니다.`);
}
}, 1000);
});
promise
.then(function(num){
console.log(`2^${num} = ${Math.pow(2,num)}`);
})
.catch(function(error){
console.log(error);
});
</script>
</body>
</html>
promise.then(onFullfilled, onRejected);
then메서드의 첫 번째 인수 onFullfileed는 성공시 실행하는 콜백함수를, 두 번째 인수 onRejected는 실패시 실행하는 콜백함수를 지정할 수 있습니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> </title>
</head>
<body>
<script>
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
var n = parseInt(prompt("10 미만 숫자를 입력"));
if(n <= 10){
resolve(n);
}else{
reject(`오류: ${n}은 10 이상입니다.`);
}
}, 1000);
});
promise.then(
function(num){
console.log(`2^${num} = ${Math.pow(2,num)}`);
},
function(error){
console.log(error);
});
</script>
</body>
</html>
Promise가 실행하는 콜백 함수에 인수 넘기는 방법
Promise객체를 리턴하는 함수를 정의해서 구현합니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> </title>
</head>
<body>
<script>
function buyAsync(mymoney){
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
var payment = parseInt(prompt("지불 금액 입력"));
var balance = mymoney - payment;
if(balance > 0){
console.log(`${payment}원을 지불했습니다.`);
resolve(balance);
}else{
reject(`잔액은 ${mymoney}원 입니다. 구매할 수 없습니다.`);
}
}, 1000);
});
return promise;
}
buyAsync(500).then(
function(balance){
console.log(`잔액은 ${balance}원 입니다.`);
},
function(error){
console.log(error);
}
);
</script>
</body>
</html>
비동기 처리 연결
위의 예제를 then메서드를 반복 연결해서 비동기 처리를 연결 할 수 있습니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> </title>
</head>
<body>
<script>
function buyAsync(mymoney){
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
var payment = parseInt(prompt("지불 금액 입력"));
var balance = mymoney - payment;
if(balance > 0){
console.log(`${payment}원을 지불했습니다.`);
resolve(balance);
}else{
reject(`잔액은 ${mymoney}원 입니다. 구매할 수 없습니다.`);
}
}, 1000);
});
return promise;
}
buyAsync(500)
.then(function(balance){
console.log(`잔액은 ${balance}원 입니다.`);
return buyAsync(balance);
})
.then(function(balance){
console.log(`잔액은 ${balance}원 입니다.`);
return buyAsync(balance);
})
.then(function(balance){
console.log(`잔액은 ${balance}원 입니다.`);
return buyAsync(balance);
})
.catch(function(error){
console.log(error);
});
</script>
</body>
</html>
비동기 처리 병렬로 실행
Promise.all(iterable);
비동기 함수로된 배열(iterable객체)을 병렬로 실행합니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> </title>
</head>
<body>
<script>
function buyAsync(name, mymoney){
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
var payment = parseInt(prompt("지불 금액 입력"));
var balance = mymoney - payment;
if(balance > 0){
console.log(`${name}: ${payment}원을 지불했습니다.`);
resolve(balance);
}else{
reject(`${name}: 잔액은 ${mymoney}원 입니다. 구매할 수 없습니다.`);
}
}, 1000);
});
return promise;
}
Promise.all([
buyAsync("Tom", 500),
buyAsync("Huck", 600),
buyAsync("Becky", 1000)
])
.then(function(balance){
console.log(balance);
})
.catch(function(error){
console.log(error);
});
</script>
</body>
</html>
Promise.race(iterable);
비동기 작업 중에 가장 먼저 종료한 Promise 객체의 결과만 다음 작업으로 보냅니다.
나머지 작업들은 실행되긴 하지만 가장 먼저 종료한 작업의 결과값만 리턴합니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> </title>
</head>
<body>
<script>
function buyAsync(name, mymoney){
var promise = new Promise(function(resolve, reject){
setTimeout(function(){
var payment = parseInt(prompt("지불 금액 입력"));
var balance = mymoney - payment;
if(balance > 0){
console.log(`${name}: ${payment}원을 지불했습니다.`);
resolve(balance);
}else{
reject(`${name}: 잔액은 ${mymoney}원 입니다. 구매할 수 없습니다.`);
}
}, 1000);
});
return promise;
}
Promise.race([
buyAsync("Tom", 500),
buyAsync("Huck", 600),
buyAsync("Becky", 1000)
])
.then(function(balance){
console.log(balance);
})
.catch(function(error){
console.log(error);
});
</script>
</body>
</html>
'DEV&OPS > Javascript' 카테고리의 다른 글
javascript class (0) | 2022.03.15 |
---|---|
Ajax (0) | 2022.03.12 |
javascript event (0) | 2022.03.11 |
javascript DOM tree (0) | 2022.03.06 |
javascript 브라우저의 객체 (0) | 2022.03.04 |