Không. Chúng tôi chưa thể làm điều đó.
ES6 lời hứa không hỗ trợ hủy bỏ chưa . Nó đang trên đà phát triển và thiết kế của nó là thứ mà rất nhiều người đã làm việc rất chăm chỉ. Khó có thể hiểu đúng ngữ nghĩa của việc hủy âm thanh và điều này đang được tiến hành. Có những cuộc tranh luận thú vị về repo "tìm nạp", trên esdiscuss và trên một số repo khác trên GH nhưng tôi sẽ kiên nhẫn nếu tôi là bạn.
Nhưng, nhưng, nhưng .. hủy bỏ là thực sự quan trọng!
Đó là, thực tế của vấn đề là hủy bỏ thực sự là một kịch bản quan trọng trong lập trình phía máy khách. Các trường hợp bạn mô tả như hủy bỏ yêu cầu web là quan trọng và chúng ở khắp mọi nơi.
Vì vậy, ... ngôn ngữ đã làm tôi say mê!
Vâng, xin lỗi về điều đó. Lời hứa phải có trước khi những thứ khác được chỉ định - vì vậy họ đã đi vào mà không có một số thứ hữu ích như .finally
và .cancel
- mặc dù vậy, nó đang trên đường đến thông số kỹ thuật thông qua DOM. Hủy bỏ không phải là một suy nghĩ sau đó mà chỉ là một hạn chế về thời gian và một cách tiếp cận lặp đi lặp lại nhiều hơn đối với thiết kế API.
Vậy tôi có thể làm gì?
Bạn có một số lựa chọn thay thế:
- Sử dụng thư viện của bên thứ ba như bluebird có thể di chuyển nhanh hơn rất nhiều so với thông số kỹ thuật và do đó có khả năng hủy bỏ cũng như một loạt các tiện ích khác - đây là những gì các công ty lớn như WhatsApp làm.
- Chuyển mã thông báo hủy .
Sử dụng thư viện của bên thứ ba là điều khá hiển nhiên. Đối với mã thông báo, bạn có thể đặt phương thức của mình đưa một hàm vào và sau đó gọi nó, chẳng hạn như:
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;
});
};
Điều đó sẽ cho phép bạn làm:
var token = {};
var promise = getWithCancel("/someUrl", token);
token.cancel();
Trường hợp sử dụng thực tế của bạn - last
Điều này không quá khó với cách tiếp cận mã thông báo:
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);
};
}
Điều đó sẽ cho phép bạn làm:
var synced = last(getWithCancel);
synced("/url1?q=a");
synced("/url1?q=ab");
synced("/url1?q=abc");
synced("/url1?q=abcd").then(function() {
});
Và không, các thư viện như Bacon và Rx không "tỏa sáng" ở đây bởi vì chúng là các thư viện có thể quan sát được, chúng chỉ có cùng lợi thế mà các thư viện hứa hẹn cấp người dùng có được là không bị ràng buộc về đặc điểm kỹ thuật. Tôi đoán chúng ta sẽ chờ đợi và xem trong ES2016 khi nào các vật thể quan sát trở thành bản địa. Tuy nhiên, chúng rất tiện lợi cho người đánh máy.