Rückruf Hölle bedeutet, dass Sie sich innerhalb eines Rückrufs innerhalb eines anderen Rückrufs befinden und es zum n-ten Anruf geht, bis Ihre Bedürfnisse nicht erfüllt sind.
Lassen Sie uns anhand eines Beispiels für einen gefälschten Ajax-Aufruf mithilfe der festgelegten Zeitüberschreitungs-API verstehen, dass wir eine Rezept-API haben und alle Rezepte herunterladen müssen.
<body>
<script>
function getRecipe(){
setTimeout(()=>{
const recipeId = [83938, 73838, 7638];
console.log(recipeId);
}, 1500);
}
getRecipe();
</script>
</body>
Im obigen Beispiel wird nach 1,5 Sekunden, wenn der Timer innerhalb des Rückrufcodes abläuft, ausgeführt. Mit anderen Worten, durch unseren gefälschten Ajax-Aufruf werden alle Rezepte vom Server heruntergeladen. Jetzt müssen wir bestimmte Rezeptdaten herunterladen.
<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>
Um bestimmte Rezeptdaten herunterzuladen, haben wir Code in unseren ersten Rückruf geschrieben und die Rezept-ID übergeben.
Angenommen, wir müssen alle Rezepte desselben Herausgebers des Rezepts herunterladen, dessen ID 7638 lautet.
<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>
Um unsere Anforderungen zu erfüllen, dh alle Rezepte des Herausgebernamens suru herunterzuladen, haben wir in unserem zweiten Rückruf Code geschrieben. Es ist klar, dass wir eine Rückrufkette geschrieben haben, die Rückrufhölle heißt.
Wenn Sie die Hölle des Rückrufs vermeiden möchten, können Sie Promise verwenden, die js es6-Funktion. Jedes Versprechen erhält einen Rückruf, der aufgerufen wird, wenn ein Versprechen vollständig erfüllt ist. Versprechen Rückruf hat zwei Optionen, entweder es wird gelöst oder abgelehnt. Angenommen, Ihr API-Aufruf ist erfolgreich. Sie können die Auflösung aufrufen und Daten durch die Auflösung übergeben . Sie können diese Daten mit then () abrufen . Wenn Ihre API jedoch fehlgeschlagen ist, können Sie Reject verwenden. Verwenden Sie catch , um den Fehler abzufangen. Denken Sie daran, ein Versprechen immer dann für die Lösung zu verwenden und für die Ablehnung zu fangen
Lassen Sie uns das vorherige Problem der Rückrufhölle mit einem Versprechen lösen.
<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>
Laden Sie jetzt ein bestimmtes Rezept herunter:
<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>
Jetzt können wir eine andere Methode schreiben, die allRecipeOfAPublisher aufruft, wie getRecipe, die ebenfalls ein Versprechen zurückgibt, und wir können eine weitere then () schreiben, um ein Auflösungsversprechen für allRecipeOfAPublisher zu erhalten. Ich hoffe, dass Sie dies an dieser Stelle selbst tun können.
Wir haben also gelernt, wie man Versprechen konstruiert und konsumiert. Lassen Sie uns nun das Konsumieren von Versprechen vereinfachen, indem wir async / await verwenden, das in es8 eingeführt wird.
<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>
Im obigen Beispiel haben wir eine asynchrone Funktion verwendet, da sie im Hintergrund ausgeführt wird. Innerhalb der asynchronen Funktion haben wir das Schlüsselwort await vor jeder Methode verwendet, die zurückgibt oder ein Versprechen ist, weil wir an dieser Position warten müssen, bis dieses Versprechen erfüllt ist, mit anderen Worten in der Balgcodes, bis getIds abgeschlossen ist, aufgelöst oder Programm abgelehnt, führen die Ausführung von Codes unter dieser Zeile nicht mehr aus, wenn IDs zurückgegeben werden. Dann haben wir die Funktion getRecipe () erneut mit einer ID aufgerufen und mit dem Schlüsselwort await gewartet, bis Daten zurückgegeben wurden. So haben wir uns endlich von der Rückrufhölle erholt.
async function getRecipesAw(){
const IDs = await getIds;
console.log(IDs);
const recipe = await getRecipe(IDs[2]);
console.log(recipe);
}
Um wait verwenden zu können, benötigen wir eine asynchrone Funktion. Wir können ein Versprechen zurückgeben. Verwenden Sie es dann, um das Versprechen zu lösen, und kath, um das Versprechen abzulehnen
aus dem obigen Beispiel:
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);
});