Tidak. Kita belum bisa melakukannya.
ES6 janji tidak mendukung pembatalan belum . Sedang dalam perjalanan, dan desainnya adalah sesuatu yang dikerjakan dengan sangat keras oleh banyak orang. Semantik pembatalan suara sulit dilakukan dengan benar dan ini sedang dalam proses. Ada perdebatan menarik tentang "fetch" repo, esdiscuss dan beberapa repo lain di GH tapi saya hanya akan bersabar jika saya jadi Anda.
Tapi, tapi, tapi .. pembatalan itu sangat penting!
Hal ini, kenyataan yang terjadi adalah pembatalan adalah benar-benar skenario penting dalam pemrograman sisi klien. Kasus yang Anda gambarkan seperti membatalkan permintaan web itu penting dan ada di mana-mana.
Jadi ... bahasanya mengacaukan saya!
Ya, maaf soal itu. Janji harus masuk terlebih dahulu sebelum hal-hal lebih lanjut ditentukan - jadi janji masuk tanpa beberapa hal berguna seperti .finally
dan .cancel
- meskipun sedang dalam perjalanan, ke spesifikasi melalui DOM. Pembatalan bukanlah renungan, ini hanya kendala waktu dan pendekatan yang lebih berulang untuk desain API.
Jadi apa yang bisa kulakukan?
Anda memiliki beberapa alternatif:
- Gunakan pustaka pihak ketiga seperti bluebird yang dapat bergerak jauh lebih cepat daripada spesifikasi dan dengan demikian memiliki pembatalan serta banyak hal lainnya - inilah yang dilakukan oleh perusahaan besar seperti WhatsApp.
- Lulus token pembatalan .
Menggunakan pustaka pihak ketiga cukup jelas. Adapun token, Anda bisa membuat metode Anda mengambil fungsi dan kemudian memanggilnya, seperti:
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;
});
};
Yang memungkinkan Anda melakukan:
var token = {};
var promise = getWithCancel("/someUrl", token);
token.cancel();
Kasus penggunaan Anda yang sebenarnya - last
Ini tidak terlalu sulit dengan pendekatan token:
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);
};
}
Yang memungkinkan Anda melakukan:
var synced = last(getWithCancel);
synced("/url1?q=a");
synced("/url1?q=ab");
synced("/url1?q=abc");
synced("/url1?q=abcd").then(function() {
});
Dan tidak, perpustakaan seperti Bacon dan Rx tidak "bersinar" di sini karena mereka adalah perpustakaan yang dapat diamati, mereka hanya memiliki keuntungan yang sama dengan perpustakaan janji tingkat pengguna dengan tidak terikat spesifikasi. Saya kira kita akan menunggu untuk memilikinya dan melihat di ES2016 ketika observable menjadi native. Mereka adalah bagus untuk typeahead sekalipun.