Non, nous ne pouvons pas encore faire ça.
Promesses ES6 ne prennent pas en charge l' annulation encore . Il est en route et sa conception est quelque chose sur lequel beaucoup de gens ont travaillé très dur. La sémantique d'annulation du son est difficile à maîtriser et c'est un travail en cours. Il y a des débats intéressants sur le repo «fetch», sur esdiscuss et sur plusieurs autres dépôts sur GH mais je serais juste patient si j'étais vous.
Mais, mais, mais ... l'annulation est vraiment importante!
C'est vrai, la réalité de la question est que l'annulation est vraiment un scénario important dans la programmation côté client. Les cas que vous décrivez comme l'annulation de requêtes Web sont importants et ils sont partout.
Alors ... la langue m'a foutu!
Ouais, désolé pour ça. Les promesses devaient être reçues en premier avant que d'autres choses ne soient spécifiées - elles sont donc entrées sans certaines choses utiles comme .finally
et .cancel
- elles sont en route cependant, vers les spécifications via le DOM. L'annulation n'est pas une réflexion après coup, c'est juste une contrainte de temps et une approche plus itérative de la conception d'API.
Alors qu'est-ce que je peux faire?
Vous avez plusieurs alternatives:
- Utilisez une bibliothèque tierce comme bluebird qui peut se déplacer beaucoup plus rapidement que la spécification et donc avoir une annulation ainsi qu'un tas d'autres goodies - c'est ce que font les grandes entreprises comme WhatsApp.
- Transmettez un jeton d' annulation .
L'utilisation d'une bibliothèque tierce est assez évidente. En ce qui concerne un jeton, vous pouvez faire en sorte que votre méthode prenne une fonction, puis l'appelle comme telle:
function getWithCancel(url, token) {
var xhr = new XMLHttpRequest;
xhr.open("GET", url);
return new Promise(function(resolve, reject) {
xhr.onload = function() { resolve(xhr.responseText); });
token.cancel = function() {
xhr.abort();
reject(new Error("Cancelled"));
};
xhr.onerror = reject;
});
};
Ce qui vous permettrait de faire:
var token = {};
var promise = getWithCancel("/someUrl", token);
token.cancel();
Votre cas d'utilisation réel - last
Ce n'est pas trop difficile avec l'approche des jetons:
function last(fn) {
var lastToken = { cancel: function(){} };
return function() {
lastToken.cancel();
var args = Array.prototype.slice.call(arguments);
args.push(lastToken);
return fn.apply(this, args);
};
}
Ce qui vous permettrait de faire:
var synced = last(getWithCancel);
synced("/url1?q=a");
synced("/url1?q=ab");
synced("/url1?q=abc");
synced("/url1?q=abcd").then(function() {
});
Et non, les bibliothèques comme Bacon et Rx ne «brillent» pas ici parce que ce sont des bibliothèques observables, elles ont juste le même avantage que les bibliothèques de promesse de niveau utilisateur ont en n'étant pas liées aux spécifications. Je suppose que nous attendrons d'avoir et de voir dans ES2016 quand les observables deviendront natifs. Ils sont cependant très pratiques pour la tête de frappe.