Panggil kembali neraka berarti Anda berada di dalam panggilan balik dari dalam panggilan balik lain dan itu pergi ke panggilan n sampai kebutuhan Anda tidak terpenuhi.
Mari kita pahami melalui contoh panggilan ajax palsu dengan menggunakan set timeout API, mari kita asumsikan kita memiliki API resep, kita perlu mengunduh semua resep.
<body>
<script>
function getRecipe(){
setTimeout(()=>{
const recipeId = [83938, 73838, 7638];
console.log(recipeId);
}, 1500);
}
getRecipe();
</script>
</body>
Pada contoh di atas setelah 1,5 detik ketika timer berakhir di dalam kode panggilan balik akan dijalankan, dengan kata lain, melalui panggilan ajax palsu kita semua resep akan diunduh dari server. Sekarang kita perlu mendownload data resep tertentu.
<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>
Untuk mengunduh data resep tertentu, kami menulis kode di dalam panggilan balik pertama kami dan meneruskan ID resep.
Sekarang katakanlah kita perlu mengunduh semua resep dari penerbit resep yang sama dengan 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>
Untuk memenuhi kebutuhan kami yaitu mengunduh semua resep nama penerbit suru, kami menulis kode di dalam panggilan balik kedua kami. Jelas kami menulis rantai panggilan balik yang disebut neraka panggilan balik.
Jika Anda ingin menghindari callback hell, Anda bisa menggunakan Promise, yaitu fitur js es6, setiap Promise menerima panggilan balik yang dipanggil saat sebuah promise terisi penuh. janji panggilan balik memiliki dua opsi baik itu diselesaikan atau ditolak. Misalkan panggilan API Anda berhasil, Anda dapat memanggil penyelesaian dan meneruskan data melalui penyelesaian , Anda bisa mendapatkan data ini dengan menggunakan then () . Tetapi jika API Anda gagal, Anda dapat menggunakan reject, gunakan catch untuk menangkap kesalahan. Ingat janji selalu menggunakan kemudian untuk tekad dan menangkap untuk menolak
Mari kita selesaikan masalah callback hell sebelumnya menggunakan sebuah 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>
Sekarang unduh resep tertentu:
<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>
Sekarang kita dapat menulis metode lain memanggil allRecipeOfAPublisher seperti getRecipe yang juga akan mengembalikan sebuah janji, dan kita dapat menulis kemudian () lain untuk menerima janji penyelesaian untuk allRecipeOfAPublisher, saya harap pada titik ini Anda dapat melakukannya sendiri.
Jadi kita belajar bagaimana membuat dan menggunakan promise, sekarang mari kita buat penggunaan promise lebih mudah dengan menggunakan async / await yang diperkenalkan di es8.
<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>
Dalam contoh di atas, kami menggunakan fungsi async karena akan berjalan di latar belakang, di dalam fungsi async kami menggunakan kata kunci await sebelum setiap metode yang mengembalikan atau merupakan janji karena menunggu di posisi itu sampai janji itu terpenuhi, dengan kata lain di Kode di bawah sampai getIds selesai diselesaikan atau program tolak akan berhenti mengeksekusi kode di bawah baris itu ketika ID dikembalikan maka kita kembali memanggil fungsi getRecipe () dengan id dan menunggu dengan menggunakan kata kunci menunggu sampai data dikembalikan. Jadi inilah bagaimana akhirnya kami pulih dari neraka panggilan balik.
async function getRecipesAw(){
const IDs = await getIds;
console.log(IDs);
const recipe = await getRecipe(IDs[2]);
console.log(recipe);
}
Untuk menggunakan await kita akan membutuhkan fungsi async, kita bisa mengembalikan sebuah promise jadi gunakan then untuk menyelesaikan promise dan cath untuk menolak promise
dari contoh di atas:
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);
});