Geri arama cehennemi, başka bir geri aramanın içinden bir geri aramanın içinde olduğunuz anlamına gelir ve ihtiyaçlarınız karşılanana kadar n'inci aramaya gider.
Set timeout API kullanarak sahte ajax çağrısı örneğini anlayalım, bir tarif API'miz olduğunu varsayalım, tüm tarifi indirmemiz gerekiyor.
<body>
<script>
function getRecipe(){
setTimeout(()=>{
const recipeId = [83938, 73838, 7638];
console.log(recipeId);
}, 1500);
}
getRecipe();
</script>
</body>
Yukarıdaki örnekte 1.5 saniye sonra zamanlayıcı sona erdiğinde içeriden geri arama kodu çalıştırılacak, diğer bir deyişle sahte ajax çağrımız aracılığıyla tüm tarifler sunucudan indirilecektir. Şimdi belirli bir tarif verilerini indirmemiz gerekiyor.
<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>
Belirli bir tarif verilerini indirmek için ilk geri aramamızın içine kod yazdık ve tarif kimliğini geçtik.
Şimdi diyelim ki 7638 numaralı tarifin aynı yayıncısının tüm tariflerini indirmemiz gerekiyor.
<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>
Yayıncı adı suru'nun tüm tariflerini indirmek olan ihtiyaçlarımızı tam olarak karşılamak için, ikinci geri aramamızın içine kod yazdık. Geri arama cehennemi denen bir geri arama zinciri yazdığımız açıktır.
Callback cehenneminden kaçınmak istiyorsanız, js es6 özelliği olan Promise'i kullanabilirsiniz, her söz, bir söz dolduğunda çağrılan bir geri arama alır. geri aramanın çözülmesi veya reddedilmesi için iki seçeneği vardır. API çağrısı kararlılığını arayıp aracılığıyla veri geçirebiliriz başarılı varsayalım kararlılığı , kullanarak bu verileri elde edebilirsiniz sonra () . Ancak API'niz başarısız olursa, reddetmeyi kullanabilirsiniz , hatayı yakalamak için catch'i kullanın . Her zaman kullandığınız bir Sözünü unutma sonra kararlılığı ve için yakalama reddetmek için
Bir söz kullanarak önceki geri arama cehennemi problemini çözelim.
<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>
Şimdi belirli tarifi indirin:
<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>
Şimdi allRecipeOfAPublisher gibi getRecipe gibi başka bir yöntem yazabiliriz ve bu da bir söz verir ve allRecipeOfAPublisher için çözüm sözü almak için başka bir () yazabiliriz, umarım bu noktada bunu kendiniz yapabilirsiniz.
Böylece vaatleri nasıl oluşturacağımızı ve tüketeceğimizi öğrendik, şimdi es8'de tanıtılan async / await kullanarak bir söz vermeyi kolaylaştıralım.
<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>
Yukarıdaki örnekte, arka planda çalışacağı için bir async işlevi kullandık, await anahtar sözcüğünü kullandık her yöntemden önce geri dönen ya da bir vaat çünkü bu vaat yerine getirilene kadar o konumda beklemek, başka bir deyişle getIds çözülene veya red programı tamamlanana kadar aşağıdaki kodlar, ID'ler döndüğünde bu satırın altındaki kodları yürütmeyi durduracak, sonra yine bir id ile getRecipe () işlevini çağırdık ve veri dönene kadar await anahtar sözcüğünü kullanarak bekledik. İşte sonunda geri arama cehenneminden bu şekilde kurtulduk.
async function getRecipesAw(){
const IDs = await getIds;
console.log(IDs);
const recipe = await getRecipe(IDs[2]);
console.log(recipe);
}
Await'i kullanmak için eşzamansız bir işleve ihtiyacımız olacak, bir söz verebiliriz, bu yüzden sözünü çözmek için kullanın ve sözümüzü reddetmek için katlayın
yukarıdaki örnekten:
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);
});