Call back hell은 다른 콜백 내부의 콜백 내부에 있으며 필요가 가득 차지 않을 때까지 n 번째 호출로 이동 함을 의미합니다.
set timeout API를 사용하여 가짜 ajax 호출의 예를 통해 이해하고 레시피 API가 있다고 가정하고 모든 레시피를 다운로드해야합니다.
<body>
<script>
function getRecipe(){
setTimeout(()=>{
const recipeId = [83938, 73838, 7638];
console.log(recipeId);
}, 1500);
}
getRecipe();
</script>
</body>
위의 예에서 타이머가 만료되면 1.5 초 후 콜백 코드 내부에서 실행됩니다. 즉, 가짜 아약스 호출을 통해 모든 레시피가 서버에서 다운로드됩니다. 이제 특정 레시피 데이터를 다운로드해야합니다.
<body>
<script>
function getRecipe(){
setTimeout(()=>{
const recipeId = [83938, 73838, 7638];
console.log(recipeId);
setTimeout(id=>{
const recipe = {title:'Fresh Apple Juice', publisher:'Suru'};
console.log(`${id}: ${recipe.title}`);
}, 1500, recipeId[2])
}, 1500);
}
getRecipe();
</script>
</body>
특정 레시피 데이터를 다운로드하기 위해 첫 번째 콜백 내부에 코드를 작성하고 레시피 ID를 전달했습니다.
이제 ID가 7638 인 레시피의 동일한 게시자의 모든 레시피를 다운로드해야한다고 가정 해 보겠습니다.
<body>
<script>
function getRecipe(){
setTimeout(()=>{
const recipeId = [83938, 73838, 7638];
console.log(recipeId);
setTimeout(id=>{
const recipe = {title:'Fresh Apple Juice', publisher:'Suru'};
console.log(`${id}: ${recipe.title}`);
setTimeout(publisher=>{
const recipe2 = {title:'Fresh Apple Pie', publisher:'Suru'};
console.log(recipe2);
}, 1500, recipe.publisher);
}, 1500, recipeId[2])
}, 1500);
}
getRecipe();
</script>
</body>
게시자 이름 suru의 모든 레시피를 다운로드해야하는 우리의 요구를 충족시키기 위해 두 번째 콜백 내부에 코드를 작성했습니다. 콜백 지옥이라는 콜백 체인을 작성 했음이 분명합니다.
콜백 지옥을 피하고 싶다면 js es6 기능인 Promise를 사용할 수 있습니다. 각 promise는 promise가 가득 차면 호출되는 콜백을받습니다. 프라 미스 콜백에는 해결되거나 거부되는 두 가지 옵션이 있습니다. 당신의 API 호출이이 결의를 호출하고를 통해 데이터를 전달할 수 있습니다 성공적으로 가정 해결 , 당신은 사용하여이 데이터를 얻을 수 있습니다 다음 () . 그러나 API가 실패하면 거부를 사용하고 catch 를 사용 하여 오류를 포착 할 수 있습니다 . 항상 사용 약속을 기억 한 후 해결을 위해 캐치 거부에 대한
promise를 사용하여 이전 콜백 지옥 문제를 해결해 보겠습니다.
<body>
<script>
const getIds = new Promise((resolve, reject)=>{
setTimeout(()=>{
const downloadSuccessfull = true;
const recipeId = [83938, 73838, 7638];
if(downloadSuccessfull){
resolve(recipeId);
}else{
reject('download failed 404');
}
}, 1500);
});
getIds.then(IDs=>{
console.log(IDs);
}).catch(error=>{
console.log(error);
});
</script>
</body>
이제 특정 레시피를 다운로드하십시오.
<body>
<script>
const getIds = new Promise((resolve, reject)=>{
setTimeout(()=>{
const downloadSuccessfull = true;
const recipeId = [83938, 73838, 7638];
if(downloadSuccessfull){
resolve(recipeId);
}else{
reject('download failed 404');
}
}, 1500);
});
const getRecipe = recID => {
return new Promise((resolve, reject)=>{
setTimeout(id => {
const downloadSuccessfull = true;
if (downloadSuccessfull){
const recipe = {title:'Fresh Apple Juice', publisher:'Suru'};
resolve(`${id}: ${recipe.title}`);
}else{
reject(`${id}: recipe download failed 404`);
}
}, 1500, recID)
})
}
getIds.then(IDs=>{
console.log(IDs);
return getRecipe(IDs[2]);
}).
then(recipe =>{
console.log(recipe);
})
.catch(error=>{
console.log(error);
});
</script>
</body>
이제 우리는 약속을 반환하는 getRecipe 와 같은 또 다른 메서드 호출 allRecipeOfAPublisher 를 작성할 수 있으며, 또 다른 then ()을 작성하여 allRecipeOfAPublisher에 대한 해결 약속을받을 수 있습니다.이 시점에서 직접 할 수 있기를 바랍니다.
그래서 우리는 프라 미스를 구성하고 소비하는 방법을 배웠습니다. 이제 es8에 도입 된 async / await를 사용하여 더 쉽게 프라 미스를 소비하도록하겠습니다.
<body>
<script>
const getIds = new Promise((resolve, reject)=>{
setTimeout(()=>{
const downloadSuccessfull = true;
const recipeId = [83938, 73838, 7638];
if(downloadSuccessfull){
resolve(recipeId);
}else{
reject('download failed 404');
}
}, 1500);
});
const getRecipe = recID => {
return new Promise((resolve, reject)=>{
setTimeout(id => {
const downloadSuccessfull = true;
if (downloadSuccessfull){
const recipe = {title:'Fresh Apple Juice', publisher:'Suru'};
resolve(`${id}: ${recipe.title}`);
}else{
reject(`${id}: recipe download failed 404`);
}
}, 1500, recID)
})
}
async function getRecipesAw(){
const IDs = await getIds;
console.log(IDs);
const recipe = await getRecipe(IDs[2]);
console.log(recipe);
}
getRecipesAw();
</script>
</body>
위의 예에서는 백그라운드에서 실행되기 때문에 async 함수를 사용했습니다. async 함수 내 에서 약속이 이행 될 때까지 해당 위치를 기다리기 때문에 약속 인 각 메서드 앞에 await 키워드를 사용 했습니다. getIds가 해결 될 때까지 코드를 벨로우즈하거나 프로그램을 거부하면 ID가 반환 될 때 해당 줄 아래에서 코드 실행이 중지되고 다시 ID로 getRecipe () 함수를 호출하고 데이터가 반환 될 때까지 await 키워드를 사용하여 기다립니다. 그래서 이것이 우리가 콜백 지옥에서 마침내 회복 한 방법입니다.
async function getRecipesAw(){
const IDs = await getIds;
console.log(IDs);
const recipe = await getRecipe(IDs[2]);
console.log(recipe);
}
await를 사용하려면 비동기 함수가 필요합니다. promise를 반환 할 수 있으므로 resolve promise에는 then을 사용하고 거부 promise에는 cath를 사용합니다.
위의 예에서 :
async function getRecipesAw(){
const IDs = await getIds;
const recipe = await getRecipe(IDs[2]);
return recipe;
}
getRecipesAw().then(result=>{
console.log(result);
}).catch(error=>{
console.log(error);
});