Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 25.09.2014, 23:41
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

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 или оставлять промис зависшим?
Ответить с цитированием
  #2 (permalink)  
Старый 25.09.2014, 23:47
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

делай так, никто не запрещает
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();

// пофантазируй =)
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 26.09.2014 в 00:10.
Ответить с цитированием
  #3 (permalink)  
Старый 26.09.2014, 00:06
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

да, здесь как раз пригодится поддержка thenable value, из requestа буду возвращать не настоящий промис, а объект с методоми then и cancel, не, не прокатит
жаль наследовать от промиса нельзя

кстати Promise.cancel

Последний раз редактировалось Octane, 26.09.2014 в 00:11.
Ответить с цитированием
  #4 (permalink)  
Старый 26.09.2014, 00:16
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

еще вариант
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();


ну, т.е. крути как тебе надо)
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #5 (permalink)  
Старый 26.09.2014, 00:51
Профессор
Отправить личное сообщение для l-liava-l Посмотреть профиль Найти все сообщения от l-liava-l
 
Регистрация: 14.03.2012
Сообщений: 1,808

Octane,
nerv_,
Я не понимаю, вы просто играетесь или юзаете полифилы? Или на es6 в продакшен?
__________________
Научу себя плохому
Ответить с цитированием
  #6 (permalink)  
Старый 26.09.2014, 00:54
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

наверное, лучше сразу сделать метод getXHR
promise.getXHR().abort();


свой вариант я упростил, в реальности же там объект с параметрами, поэтому onBeforeSend не так страшно смотрится

Последний раз редактировалось Octane, 26.09.2014 в 01:05.
Ответить с цитированием
  #7 (permalink)  
Старый 26.09.2014, 00:59
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Сообщение от l-liava-l
Я не понимаю, вы просто играетесь или юзаете полифилы? Или на es6 в продакшен?
Promise уже в stable версиях Firefox, Chrome и Safari, и прекрасно полифилится, почему бы не юзать прямо сейчас?
Ответить с цитированием
  #8 (permalink)  
Старый 26.09.2014, 01:09
Профессор
Отправить личное сообщение для l-liava-l Посмотреть профиль Найти все сообщения от l-liava-l
 
Регистрация: 14.03.2012
Сообщений: 1,808

Цитата:
Promise уже в stable версиях Firefox, Chrome и Safari, и прекрасно полифилится, почему бы не юзать прямо сейчас?
Просто я упустил момент
__________________
Научу себя плохому
Ответить с цитированием
  #9 (permalink)  
Старый 26.09.2014, 10:59
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Так а чо какие мнения по поводу abort, это же не ошибка, всеравно реджектить?
стандартный onerror не срабатывает при abort
Ответить с цитированием
  #10 (permalink)  
Старый 26.09.2014, 11:01
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Octane, throw new Error вызовет reject внутри полифила?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтоб ссылка появлялась один раз для каждого пользователя (по IP или Cookies) Sequoia Общие вопросы Javascript 2 28.01.2010 19:16
Игра орел или решка на jquery. В любом случаи выводит вы проиграли! Dimaz jQuery 4 25.12.2009 15:04
Удалить ряд символов перед или после курсора до определенного сивола brd Javascript под браузер 3 30.10.2009 08:20
Как определить цвет (темный он или светлый)? mouse_web Элементы интерфейса 6 22.07.2009 14:35
Как узнать свернуто окно браузера или нет. bar-boss Events/DOM/Window 3 25.09.2008 16:09