Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 03.06.2012, 18:51
Vit Vit вне форума
Аспирант
Отправить личное сообщение для Vit Посмотреть профиль Найти все сообщения от Vit
 
Регистрация: 11.01.2012
Сообщений: 56

Коректность алгоритма
Всем доброго.
Скажите пожалуйста насколько корректен выбранный мною алгоритм с точки зрения "замусоривания памяти"

Есть конструктор:
function go(){
 return{
   Send:function (param,OnOk,OnFail){
     var _ajax=ajax();
	 if(!_ajax){alert("Браузер не поддерживает AJAX"); return;}
	 _ajax.open("GET",serv+'?'+param,true);
	 _ajax.onreadystatechange=function(){
		if (_ajax.readyState == 4){ 
		  if(_ajax.status==200){
		   var a=_ajax.responseText.substring(0,6);
		   if(a!='Error-') OnOk(_ajax.responseText)
		   else OnFail(_ajax.responseText);
		  };
		  if (_ajax.status!=200){OnFail("Неудачная попытка связи.");}
		 }
		};
	 _ajax.send(null);
   }
 }
}

Где ajax() - функа создаюшая объект XMLHttpRequest.

Вызов производится так:
var t=go();
 t.Send(p,function(s){alert("Удачно "+s);},function(s){alert("Не удачно "+s);});

p - параметры запроса

Не попадаю ли я таким методом на утечку памяти?
Ведь я фактически создаю объекты но не освобождаю явно после отработки?

Правильно ли я поступаю или есть другой более лучший способ, который не заставит браузер оставлять мусор?
Ответить с цитированием
  #2 (permalink)  
Старый 03.06.2012, 19:15
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Vit
Не попадаю ли я таким методом на утечку памяти?
Ведь я фактически создаю объекты но не освобождаю явно после отработки?
в js есть сборщик мусора, так что опасаться не стоит. стоит только избегать замыканий, где они не нужны.

а вот этого лучше избегать, т.к. переменные не будут очищаться до того, как функция обработки завершения запроса не прекратит работу.
_ajax.onreadystatechange=function(){
		if (_ajax.readyState == 4){

лучше сделать так - в this будет XMLHttpRequest, для которого в текущий момент обрабатывается событие. всё так же, как и в элементах.
_ajax.onreadystatechange=function(){
		if (*!*this*/!*.readyState == 4){

а лучше - даже так - вынести обработчик куда-нибудь в долгую память.
function handler(){
    if (this.readyState == 4){ 
    //......
}

// function go ....
    _ajax.onreadystatechange = *!*handler*/!*;

Последний раз редактировалось melky, 03.06.2012 в 19:18.
Ответить с цитированием
  #3 (permalink)  
Старый 03.06.2012, 19:17
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Сообщение от melky
лучше сделать так:
_ajax.onreadystatechange=function(){         if (this.readyState == 4){
в ИЕ это вызовет ошибку. Так как this там не будет равен xhr
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
  #4 (permalink)  
Старый 03.06.2012, 19:30
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от devote Посмотреть сообщение
в ИЕ это вызовет ошибку. Так как this там не будет равен xhr
Вот, посмотрите
http://jsfiddle.net/yPKkJ/
В IE10 в режиме эмуляции IE8,IE7 всё нормально.

Или Вы ActiveX компонент имели в виду?
Ответить с цитированием
  #5 (permalink)  
Старый 03.06.2012, 19:30
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

melky,
хотя эта проблема наблюдается в ИЕ6 тогда да, можно поставить this. Я что-то старой инфой оперирую
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
  #6 (permalink)  
Старый 03.06.2012, 19:31
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Сообщение от melky
Вот, посмотрите
да я только что проверил в локалке.. ИЕ6 в попе, остальные норм.
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
  #7 (permalink)  
Старый 03.06.2012, 19:45
Vit Vit вне форума
Аспирант
Отправить личное сообщение для Vit Посмотреть профиль Найти все сообщения от Vit
 
Регистрация: 11.01.2012
Сообщений: 56

Сообщение от devote Посмотреть сообщение
ИЕ6 в попе, остальные норм.
Ишачок меня мало интерсует в рамках конкретно этого проекта.
По крайней мере устаревшие браузеры уж точно не интересуют.
Цитата:
вынести обработчик куда-нибудь в долгую память.
А почему?
И как правильно описать handler(), дабы он входил в состав объекта, и видел OnOk и OnFail?
Ответить с цитированием
  #8 (permalink)  
Старый 03.06.2012, 20:35
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Vit
А почему?
Потому что когда Вы каждый раз пишете el.onclick = function(){ ..., Вы каждый раз убиваете котёнка создаёте новую функцию. А делая, как я показал, Вы используете одну каждый раз.

Сообщение от devote
да я только что проверил в локалке.. ИЕ6 в попе, остальные норм.
Я не пишу под него, как и под FF 3.6. Я в стаде .

Сообщение от Vit
И как правильно описать handler(), дабы он входил в состав объекта, и видел OnOk и OnFail?
Самое простое - записать их в объект какой-нибудь, а его уже сохранить в замыкании.
http://jsfiddle.net/yPKkJ/2/
Боялся, что IE не понравится custom свойство id ... но, вроде, пережевал.
(function() {

    var running = {};

    function noop() {}

    function handler() {
        if (this.readyState === 4) {
            (running[this.id][this.status === 200 ? "onsuccess" : "onerror"] || noop).call(this);
            delete running[this.id]; // убиваем сами обработчиков. не нужны уже.
        }
    }

    window.send = function(url, method, data, onsuccess, onerror) {
        var req = new XMLHttpRequest();
        req.open(method, url, true);
        req.onreadystatechange = handler;
        req.send(data);
        req.id = (Math.random() * 1e5 | 0).toString(32); // случайна последовательность англ. букв и цифр. 
        running[req.id] = { // сохраняем, пока не понадобятся
            "onsuccess": onsuccess,
            "onerror": onerror
        };
    }
})();

Последний раз редактировалось melky, 03.06.2012 в 20:39.
Ответить с цитированием
  #9 (permalink)  
Старый 03.06.2012, 21:03
Vit Vit вне форума
Аспирант
Отправить личное сообщение для Vit Посмотреть профиль Найти все сообщения от Vit
 
Регистрация: 11.01.2012
Сообщений: 56

Т.е. мне лучше описать handler как private метод объекта, и присваивать его onreadystatechange, дабы каждый раз не "создавать" анонимную функцию.
При этом поскольку сам handler будет принадлежать объекту я смогу в нем вызывать мои OnOk и OnFail?
Верно я понял?
Ответить с цитированием
  #10 (permalink)  
Старый 03.06.2012, 21:12
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Vit
Верно я понял?
Если взять объект, "которому принадлежит handler", за req, а "смогу вызывать onOk .." - за итог, то да, верно.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Реализация алгоритма (массив координат) ed_17 Общие вопросы Javascript 1 02.03.2011 19:25