Nie. Jeszcze nie możemy tego zrobić.
Obietnice ES6 nie obsługują jeszcze anulowania . Jest w drodze, a jego projekt to coś, nad czym naprawdę ciężko pracowało wiele osób. Semantyka eliminacji dźwięku jest trudna do ustalenia, a prace nad tym trwają. Trwają interesujące debaty na temat repozytorium „fetch”, esdiscussów i kilku innych repozytoriów na GH, ale byłbym cierpliwy, gdybym był tobą.
Ale, ale, ale… odwołanie jest naprawdę ważne!
To znaczy, rzeczywistość jest taka, że anulowanie jest naprawdę ważnym scenariuszem w programowaniu po stronie klienta. Przypadki, które opisujesz jako przerywanie żądań sieci Web, są ważne i są wszędzie.
Więc ... język mnie przeleciał!
Tak, przepraszam za to. Obietnice musiały pojawić się jako pierwsze, zanim dalsze rzeczy zostały określone - więc weszły bez pewnych przydatnych rzeczy, takich jak .finally
i .cancel
- jednak jest w drodze do specyfikacji przez DOM. Anulowanie to nie tylko refleksja, to tylko ograniczenie czasowe i bardziej iteracyjne podejście do projektowania interfejsu API.
Więc co mogę zrobić?
Masz kilka alternatyw:
- Skorzystaj z biblioteki innej firmy, takiej jak bluebird, która może poruszać się znacznie szybciej niż specyfikacja, a tym samym ma anulowanie, a także kilka innych gadżetów - tak robią duże firmy, takie jak WhatsApp.
- Przekaż token anulowania .
Korzystanie z biblioteki innej firmy jest dość oczywiste. Jeśli chodzi o token, możesz sprawić, aby Twoja metoda przyjęła funkcję, a następnie ją wywołała:
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;
});
};
Co pozwoliłoby ci:
var token = {};
var promise = getWithCancel("/someUrl", token);
token.cancel();
Twój rzeczywisty przypadek użycia - last
Nie jest to zbyt trudne z podejściem tokenowym:
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);
};
}
Co pozwoliłoby ci:
var synced = last(getWithCancel);
synced("/url1?q=a");
synced("/url1?q=ab");
synced("/url1?q=abc");
synced("/url1?q=abcd").then(function() {
});
I nie, biblioteki takie jak Bacon i Rx nie „błyszczą” tutaj, ponieważ są bibliotekami obserwowalnymi, mają po prostu taką samą przewagę, jaką obietnice mają biblioteki na poziomie użytkownika, ponieważ nie są ograniczone do specyfikacji. Myślę, że będziemy czekać i zobaczyć w ES2016, kiedy obserwowalne staną się natywne. Oni są ładne na wpisywanie znaków z wyprzedzeniem chociaż.