Ні. Ми поки не можемо цього зробити.
ES6 обіцянку не підтримують скасування ще . Це вже в дорозі, і над його дизайном - це те, над чим багато людей працювали по-справжньому. Звукова семантика скасування важко отримати права , і це робота. Існують цікаві дебати щодо репо "вибору", про есдискусу та щодо кількох інших репо про GH, але на вашому місці я б просто набрався терпіння.
Але, але, але .. скасування дійсно важливо!
Це дійсність у тому, що скасування дійсно є важливим сценарієм програмування на стороні клієнта. Випадки, які ви описуєте як скасування веб-запитів, важливі, і вони є скрізь.
Отож ... мова мене накрутила!
Так, вибачте за це. Обіцянки повинні були увійти спочатку, перш ніж були визначені подальші речі, - тому вони увійшли без корисних речей, таких як .finally
і .cancel
- проте це вже на шляху, до специфікації через DOM. Скасування не є додатковою думкою, це лише обмеження у часі та більш ітеративний підхід до проектування API.
То що я можу зробити?
У вас є кілька альтернатив:
- Використовуйте сторонні бібліотеки, такі як bluebird, які можуть рухатися набагато швидше, ніж специфікація, і, таким чином, скасовують їх, а також купу інших смакот - це те, що роблять великі компанії, такі як WhatsApp.
- Передайте маркер скасування .
Використання сторонніх бібліотек досить очевидно. Що стосується маркера, ви можете змусити метод використовувати функцію, а потім викликати її як таку:
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;
});
};
Що дозволить вам зробити:
var token = {};
var promise = getWithCancel("/someUrl", token);
token.cancel();
Ваш фактичний випадок використання - last
Це не надто складно з підходом лексеми:
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);
};
}
Що дозволить вам зробити:
var synced = last(getWithCancel);
synced("/url1?q=a");
synced("/url1?q=ab");
synced("/url1?q=abc");
synced("/url1?q=abcd").then(function() {
});
І ні, бібліотеки, такі як Bacon та Rx, тут не "світяться", тому що це спостережувані бібліотеки, вони просто мають ту саму перевагу, яку мають бібліотеки обіцянок на рівні користувача, не пов'язані зі специфікацією. Я думаю, ми зачекаємо, щоб побачити і побачити в ES2016, коли спостережувані стануть рідними. Вони є чепурних для машинописного , хоча.