J'ai du mal à obtenir ma tête asynchrone / attente.
J'ai le code suivant qui appelle:
submitHandler() qui publie les entrées d'un formulaire dans des feuilles Googleasync function onSubmit() {
setTimeout(() => {
submitHandler()
childRef.current.upload()
}, 1000)
}
//I want to wait for onSubmit to complete and then call another function which sets state and then launches a modal
childRef.current.upload() qui publie un fichier sur S3 ...mais je dois attendre les résultats de ces deux fonctions avant d'appeler une autre fonction pour ouvrir un modal et transmettre les résultats de ces deux fonctions.
Est-ce que quelqu'un peut m'aider s'il vous plaît?
Merci beaucoup
const scriptURL =
'GOOGLE SCRIPT URL'
const form = document.forms.emailform
fetch(scriptURL, { method: 'POST', body: new FormData(form) })
.then(response => {
console.log('Success!', response)
setFormSuccess(1)
})
.catch(error => {
console.error('Error!', error.message)
setFormSuccess(2)
})
}
EDIT: Je dois mentionner dans la question originale que j'ai essayé d'attendre dans toutes les fonctions que j'appelle, mais aucune d'elles ne fonctionne
4 Réponses :
Je pense que vous manquez juste quelques déclarations «en attente». J'ai également modifié le délai d'expiration.
async submitHandler() {
const scriptURL = 'GOOGLE SCRIPT URL'
const form = document.forms.emailform
try {
let response = await fetch(scriptURL, { method: 'POST', body: new FormData(form) })
console.log('Success!', response)
setFormSuccess(1)
} catch(error) {
console.error('Error!', error.message)
setFormSuccess(2)
}
}
De plus, dans submitHandler (), vous n'utilisez pas correctement async-await. Vous utilisez les méthodes .then, qui ne peuvent pas être facilement combinées avec le fichier await.
async function onSubmit() {
let sleep = function (ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
await sleep(1000)
await submitHandler()
await childRef.current.upload()
}
//I want to wait for onSubmit to complete and then call another function which sets state and then launches a modal
Si vous voulez toujours attraper des erreurs, vous devez encapsuler la récupération dans un bloc try.
Merci désolé j'ai oublié de mentionner que l'attente submitHandler () donne une erreur qui attend n'est autorisée que dans les fonctions asynchrones
J'étais trop rapide, j'ai édité ma réponse. J'espère que cela aide :)
merci @kevin. Cela vient avec 'attendre' n'a aucun effet sur ce type d'expression
sur la fonction submitHandler (). J'ai ajouté cette fonction à la question maintenant
C'est un grand merci @kevin. Pourriez-vous me donner un guide sur le bloc de récupération pour l'équivalent de capture
@NickWild je l'ai ajouté à ma réponse. Je vous serais reconnaissant si vous pouviez marquer ma réponse comme acceptée si cela aidait :)
Brililant merci beaucoup @kevin. Je ne sais toujours pas si je fais ça mais ça résout mon problème et j'essaierai d'en savoir plus à ce sujet.
Votre fonction doit renvoyer Promise . Alors retournez votre fetch()
async function onSubmit() {
setTimeout(() => {
const response = await submitHandler()
// Your response will be available here
console.log(response);
childRef.current.upload()
}, 1000)
}
Donc à ta fonction principale tu pourrais
submitHeader(){
const scriptURL =
'GOOGLE SCRIPT URL'
const form = document.forms.emailform
return fetch(scriptURL, { method: 'POST', body: new FormData(form) })
.then(response => {
console.log('Success!', response)
setFormSuccess(1)
return response;
})
.catch(error => {
console.error('Error!', error.message)
setFormSuccess(2)
})
}
Merci, j'ai oublié de mentionner que j'avais essayé attendre sur toutes les fonctions et aucune d'elles ne fonctionnait. Je vais modifier ma question maintenant
mais il est important que votre fonction retourne attendre ne puisse être utilisée qu'avec Promise return.
La fonction de gestionnaire d'envoi publie dans un script google avec une récupération, puis capture ce changement d'état à ce moment-là et capture selon que la récupération est réussie ou non. Désolé d'être si stupide là-dessus! :-)
pourriez-vous montrer un extrait de code s'il vous plaît? Il m'est impossible de vous aider quand nous n'avons pas de réels retours de vos fonctions
Merci @Filip J'ai ajouté le code du submitHandler () à la question d'origine. S'il vous plaît laissez-moi savoir si vous avez besoin de quelque chose d'autre
La première chose est que vous devez marquer le rappel de setTimeout comme async si vous voulez l' await intérieur.
Mais setTimeout utilise des callbacks et s'écarte ainsi du flux de contrôle souhaité. Ainsi, j'utiliserais un simple wrapper de promesse pour y arriver:
function onSubmit() {
return promiseSetTimeout(async () => {
await submitHandler();
await childRef.current.upload();
}, 1000);
}
Ainsi, vous pouvez attendre dessus et avoir le flux de contrôle souhaité.
const promiseSetTimeout = (cb, delay) => new Promise((resolve, reject) => {
setTimeout(async () => {
const ret = await cb();
resolve(ret);
}, delay);
});
Merci @Vivick je reçois une promesseSetTimeout n'est pas défini
Vous avez copié l'implémentation que je vous ai donnée dans le même fichier (ou l'avez-vous importée si elle se trouve ailleurs)?
Merci oui Dans le même fichier - je viens de copier et coller. Il a également une erreur qui n'attend aucun effet sur ce type d'expression pour l'attente submitHandler ()
C'est probablement parce que ça ne rend pas une promesse
Merci d'avoir modifié la question pour inclure le submitHandler (). Des pensées?
Vous devez retourner votre appel pour fetch autre chose que cela devrait fonctionner correctement. Attendre quelque chose qui n'est pas vraiment attendu ne sera pas un problème
Vous pouvez utiliser Promise.all () pour attendre plusieurs promesses, comme ceci
const result = await Promise.all([submitHandler(), childRef.current.upload()]);
Merci @riwen. Bien que la réponse de Kevinkreps ait résolu mon problème, j'en ai également besoin pour attendre la deuxième fonction.
taniarascia.com/promise-all-with-async-await