let printString = function(str){
setTimeout(
()=>{
console.log(str);
},
Math.floor(Math.random()*100)+1
)
}
let printAll = () =>{
printString("A");
printString("B");
printString("C");
}
printAll();
위에 보이는 코드는 순서대로 실행되지 않는다.
순서대로 해결하기 위해서는 Callback을 사용해야한다.
Callback을 사용한 순서대로 실행하는 방법을 써보겠다.
let printString = (string, callback) => {
setTimeout(
() => {
console.log(string)
callback()
},
Math.floor(Math.random() * 100) + 1
)
}
let printAll = () => {
printString("A", () => {
printString("B", () => {
printString("C", () => {})
})
})
}
printAll()
CallBack은 함수를 parameter로 받아 함수안에서 사용 할 수 있도록 만드는 방법을 말한다. 하지만 이런 Callback은 많아지면 가독성이 굉장히 낮아지게 된다.
이런 callback hell이 일어난다면 읽기도 힘들뿐더러 수정도 굉장히 힘들다. javascript는 promise라는 생성자를 이용해 이를 해결 할 수 있다.
const printString = (string) => {
return new Promise((resolve, reject) => {
setTimeout(
() => {
console.log(string)
resolve()
},
Math.floor(Math.random() * 100) + 1
)
})
}
const printAll = () => {
printString("A")
.then(() => {
return printString("B")
})
.then(() => {
return printString("C")
})
}
printAll()
위 과정은 callback에서 본 코드와 같은 코드이다. promise는 resolve와 reject를 받아 사용하는데 resolve는 then을 사용해서 받는 함수를 callback해주고 reject는 catch를 사용해서 받은 함수를 callback해준다.
function buyAsync(money){
return new Promise(function(resolve,reject){
setTimeout(function(){
let payment = parseInt(prompt("지불하고자 하는 금액을 입력하세요"));
let balance = money-payment;
if(balance>0){
console.log(`${payment}원을 지불했습니다.`);
resolve(balance);
}else{
reject(`잔액은 ${money}원 입니다. 구매 불가`);
}
},1000);
});
}
buyAsync(500)
.then((balance)=>{
console.log(`잔액은 ${balance}원 입니다.`);
return buyAsync(balance);
})
.catch((error)=>{
console.log(error);
});
resolve
reject
위와 같은 결과가 나온다. balance라는 값이 부족하다면 reject가 실행되도록하고 남는다면 resolve가 실행된다. 그리고 then에 들어가 있는 함수가 resolve로 callback되고 catch에 들어가 있는 함수가 reject로 callback된다.
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
promise.all은 입력이 여러 개 일때 사용을 한다. then으로 여러개를 묶어서 만들기 보다 행렬을 한번에 쏟아 내야 하는 상황에 ALL()을 사용한다.
promise1.then(p1=>{
return promise3.then(p3=>{
console.log(p1,promise2,p3)
})
})
위와 같은 all을 사용하지 않는 다면 이런 식으로 promise가 처음 callback을 쓸때처럼 hell모양으로 가는 것을 볼 수 있다.
function buyAsync(money){
return new Promise(function(resolve,reject){
setTimeout(function(){
let payment = parseInt(prompt("지불하고자 하는 금액을 입력하세요"));
let balance = money-payment;
if(balance>0){
console.log(`${payment}원을 지불했습니다.`);
resolve(balance);
}else{
reject(`잔액은 ${money}원 입니다. 구매 불가`);
}
},1000);
});
}
let result = async()=>{
try{
let money = await buyAsync(500);
console.log(`잔액은 ${money}원 입니다.`);
}catch(error){
console.log(error)
}
}
result();
Async는 ECMAScript2017부터 정식적으로 추가 된 기능입니다. async function(){}으로 불러와도 되고 async()=>{}로 불러와도 됩니다. async로 만든 함수 안에는 awiat를 사용할 수 있습니다. try는 resolve라고 보면 되고 catch는 reject라고 생각하면 된다. await는 리턴 값을 resolve에 들어가는 값을 해준다.
var newsURL = 'http://localhost:5000/data/latestNews';
var weatherURL = 'http://localhost:5000/data/weather';
function getNewsAndWeatherAll() {
// TODO: Promise.all을 이용해 작성합니다
return Promise.all([
fetch(newsURL).then(res => res.json()),
fetch(weatherURL).then(res => res.json())
]).then(([newsData, weatherData]) => ({
news: newsData.data,
weather: weatherData
}));
// = .then(data=>{return {"news":data[0].data,"weather": data[1]};}
}
getNewsAndWeatherAll().then(data => console.log(data));
if (typeof window === 'undefined') {
module.exports = {
getNewsAndWeatherAll
}
}
fetch는 url에 접근을 해서 그 url에 필요한 값들을 받아오는 함수이다.
해당 url은 객체로 이루이진 데어터로 이루어져있다. fetch를 사용하여 데이터를 받아올 수 있고 이를 promise와 같이 사용할 수 있다.