Promise и xhr.abort или ад перфекциониста :D
вот пишем мы все реквесты на модных промисах, ну типа такого:
function request(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest;
xhr.open('GET', url);
xhr.onload = resolve;
xhr.onerror = function () {
reject(new Error(xhr.statusText));
};
xhr.send();
});
}
все красиво и замечательно выглядит, колбэковый ад позади, ничто не предвещает беды, и тут вдруг понадобилось выполнять xhr.abort(), но как?! ведь xhr объект мы получим только после окончания загрузки, в голову приходит такое извращение:
function request(url, onBeforeSend) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest;
xhr.open('GET', url);
xhr.onload = resolve;
xhr.onerror = function () {
reject(new Error(xhr.statusText));
};
if (onBeforeSend) {
onBeforeSend(xhr);
}
xhr.send();
});
}
request('…', function (xhr) {
…
//в какой-то момент выполняем
xhr.abort();
…
}).then(onFulfilled, onRejected);
вся красота порушена, нет больше идеального мира :( но это еще не все, дальше возникает вопрос, что делать после abort, выполнять onRejected или оставлять промис зависшим? |
делай так, никто не запрещает
http://stackoverflow.com/a/17328336 вообщем возвращай расширенный промис (например) у меня спец объект для работы с серваком =) Выглядит примерно так
var server = new Server(methods);
server.addMethods({
// ...
getProfile: {
method: 'POST',
url: '/demo/api/grants/get_profile.php'
},
saveProfile: {
method: 'POST',
url: '/demo/api/grants/save_profile.php'
}
// ...
});
// server.getProfile(query).success().error().then()...
// абортить можно, например, так
server.getProfile.cancel();
// пофантазируй =)
|
жаль наследовать от промиса нельзя кстати Promise.cancel :) |
еще вариант
function request(url) {
var promise = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest;
xhr.open('GET', url);
xhr.onload = resolve;
xhr.onerror = function () {
reject(new Error(xhr.statusText));
};
xhr.send();
promise.abort = xhr.abort;
});
promise.abort = noop;
return promise;
}
promise.abort();
ну, т.е. крути как тебе надо) |
Octane,
nerv_, Я не понимаю, вы просто играетесь или юзаете полифилы? Или на es6 в продакшен? |
наверное, лучше сразу сделать метод getXHR
promise.getXHR().abort(); свой вариант я упростил, в реальности же там объект с параметрами, поэтому onBeforeSend не так страшно смотрится |
Цитата:
|
Цитата:
|
Так а чо какие мнения по поводу abort, это же не ошибка, всеравно реджектить?
стандартный onerror не срабатывает при abort |
Octane, throw new Error вызовет reject внутри полифила?
|
да
|
| Часовой пояс GMT +3, время: 20:35. |