J'ai ce code (en utilisant Bluebird Promise):
const promise = loadSomething(id) .then(something => { loadParentOfSomething(something.parentId); return something; });
Quand je fais ensuite promise.cancel ()
le getSomething
est annulé, mais le getSomethingParent
ne l'est pas.
Y a-t-il un moyen de, lorsque la promesse getSomething
est annulée, je peux également obtenir le getSomethingParent
promesse d'annuler?
Les deux fonctions de chargement renvoient une promesse asynchrone annulable avec une requête HTTP, et la raison pour laquelle je veux les annuler est qu'elles peuvent parfois prendre un certain temps à se charger et quand, par exemple un utilisateur s'éloigne (SPA), la réponse n'est plus nécessaire.
3 Réponses :
Définissez une fonction comme deuxième paramètre du rappel puis
. Exemple:
const promise = getSomething(id) .then(something => { getSomethingParent(something.parentId); return something; }, error => { console.error(error) });
Lorsque vous appelez promise.reject ()
, alors getSomethingParent
ne sera pas appelé.
Référence
Cependant, getSomethingParent
a déjà été appelé. Ainsi, la promesse getSomething
a déjà été tenue, mais pas getSomethingParent
. J'aimerais que getSomethingParent
soit annulé lorsque cancel
est appelé, quel que soit l'état de getSomething
. Si ça a du sens. 🤔
Non, il ne sera appelé que lorsque getSomething
sera terminé. C'est pourquoi il est placé dans le puis
.
Si la promesse getSomething
a été tenue, comment l'annulez-vous?
Que des erreurs soient détectées n'a absolument rien à voir avec getSomethingParent
ou même avec l'annulation en général.
@Bergi par défaut si une fonction d'erreur n'est pas définie, le rappel then
est appelé à la fois en cas de succès et d'erreur. Donc, si l'utilisateur veut gérer les cas où la promesse est rejetée
, la définition d'une fonction d'erreur aidera. Voici une référence
@varunagarwal Euh, non. Vous devez avoir horriblement mal compris cette documentation. À quelle phrase faites-vous référence spécifiquement, peut-être que je peux corriger le wiki pour clarifier cela?
Oups mon mal. Désolé pour ça.
Si vous préparez une promesse factice pour référencer loadSomethingOfParent
, vous devriez pouvoir l'annuler dans loadSomething
.
function loadSomething(id, promise) { return new Promise(function(resolve, reject, onCancel) { // Do your stuff // The `.cancel()` handler onCancel(function() { promise.cancel(); }); }); }
loadSomething
aura besoin d'un gestionnaire onCancel
qui s'exécutera lorsque la promesse sera annulée.
// Create a dummy promise to reference `loadParentOfSomething` var dummyPromise = Promise.resolve(); // Pass `dummyPromise` to `loadSomething` const promise = loadSomething(id, dummyPromise).then(something => { dummyPromise = loadParentOfSomething(something.parentId); return something; });
Cela ne fonctionne pas - promise
dans loadSomething
fera toujours référence à la promesse factice Promise.resolve ()
, pas à son remplacement. JS n'a pas de pass-by-reference. Je doute également que le rappel onCancel
soit exécuté après la promesse loadSomething ()
appelée résoudre
/ rejet
.
Je pense que ce que vous recherchez réellement
const promise1 = loadSomething(id); const promise2 = promise1.then(something => { return loadParentOfSomething(something.parentId); }); // ^^^^^^ promise2.catch(e => void "ignore"); // prevent unhandled rejections
Ensuite, vous pouvez continuer à utiliser promise1
pour accéder au résultat, mais aussi appeler promise2.cancel ( )
. Cette annulation sera possible même après le règlement de promise1
.
En fait, j'ai essayé de le faire, mais cela ne semblait pas faire de différence, alors peut-être qu'il se passait autre chose ici. 🤔
… Ou peut-être que je ne comprends pas comment l'annulation de Bluebird fonctionne réellement. Attendons que Benjamin Gruenbaum vienne et confirme.
J'ai réussi à le contourner en ne faisant pas ce chargement parent car il s'est avéré que les données parentales revenaient en fait dans le cadre de something.parent
. Je pensais que c'était juste un petit extrait de code, mais après l'avoir examiné un peu plus, il s'agissait en fait à peu près des mêmes données que celles provenant de loadParentOfSomething
. Mais oui, ce serait formidable si quelqu'un pouvait faire la lumière sur cette annulation, car je pense vraiment que cela aurait dû fonctionner comme ça. 😕
getSomethingParent ()
est-il une tâche asynchrone qui peut être annulée du tout? Cela ressemble à peu près à une fonction synchrone maintenant - et vous ne faites rien avec son résultat.Oui, il renvoie également une promesse annulable. Désolé, cela aurait dû être plus clair.
Mais vous ne faites rien avec cette promesse (mais vous la jetez)? Ne recevez-vous pas un avertissement Bluebird à ce sujet ?
Pas que j'ai vu. C'est une promesse qui déclenche finalement un événement chargé via un magasin, alors il fait quelque chose. Pas juste là.
… Et à cause de cela,
promise
ne le sait pas et n'est pas incité à l'annuler.Exactement, donc je cherche un moyen de faire des promesses en quelque sorte le savoir afin qu'il puisse le faire tomber avec lui.
Voir ma réponse sur la façon de faire cela. Ou est-ce que cela ne fait pas ce que vous voulez?