Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 14.12.2013, 08:10
Аватар для lgick
Аспирант
Отправить личное сообщение для lgick Посмотреть профиль Найти все сообщения от lgick
 
Регистрация: 23.11.2013
Сообщений: 96

Как работает счетчики в js
Нужно сделать чат, чтобы можно было выводить сообщения.

Каждое сообщение живет 5 секунд (с помощью setTimeout), после этого удаляется, но перед этим постепенно угасает (тут тоже setTimeout с значением в 2 секунды).

Количество активных сообщений не должно превышать 5-ти! То есть если сообщений будет больше 5-ти, то нужно удалять их вручную.
!!! Также нужно удалять и таймеры, иначе будут выполняться команды удаления


Реализовано тут: http://learn.javascript.ru/play/UqVKb
(просто ввести сообщение и нажать enter)

Я не совсем понимаю как работают таймеры в js. Если открыть консоль, можно обнаружить что каждый последующий таймер имеет id больше предыдущего. Не происходят ли утечки памяти в моем случае?

Последний раз редактировалось lgick, 14.12.2013 в 08:56.
Ответить с цитированием
  #2 (permalink)  
Старый 14.12.2013, 09:30
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Цитата:
Если открыть консоль, можно обнаружить что каждый последующий таймер имеет id больше предыдущего.
Абсолютно штатная ситуация, так и должно быть. Мусор за таймерами будет убран сборщиком

+function f(){
    var timer=setTimeout(f,500);
    console.log(timer);
}();


При твоем подходе логика очень размазанная получается. Как минимум таймер ты мог бы разместить в модели или хотя бы в контроллере. Да и вообще добавление строки происходит предельно странно, контролер вызывает функцию в модели которая генерирует событие на которое реагирует view, view в свою очередь генерирует событие которое слушает контроллер и записывает данные в модель. Ты уверен что проще никак ? Я понимаю ради чего ты это делаешь. Независимость view ты конечно сохраняешь, но ты сохраняешь это ценой захламление модели информацией отображения, ведь line которых ты пихаешь в модель есть нечто иное как dom элемент. У тебя оветственность за связывание данных и отображения лежит на стороне модели, если перенесешь на сторону отображения то и от domизбавишся в модели, и от длинного паровоза событий при добавлении новой строки.
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 14.12.2013 в 10:46.
Ответить с цитированием
  #3 (permalink)  
Старый 14.12.2013, 11:20
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Вот переписанный пример
http://learn.javascript.ru/play/Ubsz0b

1) Я сохранил слабую связанность view и контролера.
2) Убрал dom элементы из модели
3) переложил работу с таймерами на модель
4) Убрал мусор из глобальный области видимости (ссылки на уже созданные экземпляры сделал статическим свойством singleton)

Примерно так получилось

Только одно исключение. Это то что у меня модель может сама менять свое состояние из за таймера, что на мой взгляд вполне допустимо.
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 14.12.2013 в 12:02.
Ответить с цитированием
  #4 (permalink)  
Старый 15.12.2013, 07:06
Аватар для lgick
Аспирант
Отправить личное сообщение для lgick Посмотреть профиль Найти все сообщения от lgick
 
Регистрация: 23.11.2013
Сообщений: 96

DjDiablo,

таймеры в модели? Но это же не логика. Тогда нужно передавать в модель объект window. Но window используют в представлении.. Например на window можно прослушивать события нажатия клавиш, с помощью window создавать новые элементы и тп

Сообщение от DjDiablo
ведь line которых ты пихаешь в модель есть нечто иное как dom элемент.
ну это не совсем дом элемент. В модели это просто данные. Мы просто храним некую структуру, которую потом передаем в view, который знает что это за структура и как ее использовать


Еще смущает такая логика в моем или твоем коде:

При срабатывании таймера возникает событие на удаление строки чата, которое удаляет:
1) строку чата и 2) таймер (!!!) ! Но этот таймер уже сработал (он и вызвал это событие) и поэтому удалять в принципе нечего.

Никаких ошибок не выводит, исключить это действие нельзя (мы удаляет таймер по id, а проверить его наличие перед удалением не можем)

Стоит ли на это обращать внимание?

Последний раз редактировалось lgick, 15.12.2013 в 07:23.
Ответить с цитированием
  #5 (permalink)  
Старый 15.12.2013, 07:08
Аватар для lgick
Аспирант
Отправить личное сообщение для lgick Посмотреть профиль Найти все сообщения от lgick
 
Регистрация: 23.11.2013
Сообщений: 96

DjDiablo,

как там ваш amix проект поживает?

Последний раз редактировалось lgick, 15.12.2013 в 07:33.
Ответить с цитированием
  #6 (permalink)  
Старый 15.12.2013, 08:41
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Цитата:
ну это не совсем дом элемент
ну ссылка на дум она и в Африке ссылка, если подцепить два view то они будут оба пытаться записывать данные в модель. Только представь себе последствия. Фишка независимости view как раз в том что их можно кучу наплодить без необходимости переписывания кода. Хранение данных отображения в модели сводит это преимущество на нет.

Цитата:
как там ваш amix проект поживает?
спасибо нормуль
Жаль времени мало у всех.

А чо ник сменил ?

Насчет таймера в модели если честно нет однозначного ответа.
Во первых таймер хранится в модели, и там его обработать проще всего. Как только вынесу в контроллер у меня появится потребность в событии удаления таймера, если вынесу в view то цепочка станет еще длиньше так как из view модель обычно не меняют. Может можно изловчится и не хранить таймер в модели но в голову пока нечего не приходит
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 15.12.2013 в 09:08.
Ответить с цитированием
  #7 (permalink)  
Старый 15.12.2013, 21:50
Аватар для lgick
Аспирант
Отправить личное сообщение для lgick Посмотреть профиль Найти все сообщения от lgick
 
Регистрация: 23.11.2013
Сообщений: 96

Сообщение от DjDiablo
если подцепить два view то они будут оба пытаться записывать данные в модель.
да, это не продумал. займусь на досуге

Сообщение от DjDiablo
А чо ник сменил ?
да, я и тут и на гитхабе поменял. не знаю.. просто на работе под этим ником работал, решил его оставить
Ответить с цитированием
  #8 (permalink)  
Старый 16.12.2013, 05:09
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

просто так ... почти на одном таймере ... )))
<!DOCTYPE HTML>
<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">#chat{position:absolute;bottom:0;left:0;right:0}
  #chat #chat-box{width:92%;font-size:11px;line-height:14px;margin:0 auto 40px}
  #chat #chat-box .line{opacity:1;transition:all 2s;word-wrap:break-word;text-shadow:1px 1px 1px #333;padding:2px 5px}
  #chat #chat-box .line:before{content:attr(data-name);color:#f00;margin-right:5px;font-weight:bold}
  #chat #cmd{position:absolute;left:0;right:0;bottom:0;width:92%;margin:0 auto 5px;font-size:14px;line-height:23px;outline:none;border:3px solid #099;border-radius:3px}
  </style>
</head>
<body>
<div id="chat">
    <div id="chat-box"></div>
    <input id="cmd" type="text" maxlength="150">
</div>
<script>
 var cmd = document.getElementById("cmd"),
        chatBox = document.getElementById("chat-box"),
        lines = [],
        line, timer, time;
    cmd.onkeyup = function (a) {
        a = a || window.event;
        13 === a.keyCode && cmd.value && (window.clearTimeout(timer),
        5 == lines.length && (line = lines.pop()[0],
        chatBox.removeChild(line)),
        line = document.createElement("div"),
        time = (new Date).getTime() + 5E3,
        chatBox.appendChild(line),
        line.setAttribute("data-name", "User: "),
        line.innerHTML = cmd.value,
        line.className = "line",
        lines.unshift([line, time]),
        cmd.value = "",
        removeInit())
    };
    var removeInit = function () {
        var a = lines.length - 1;
        0 > a || (time = lines[a][1] - (new Date).getTime(), 0 > time && (time = 0), timer = window.setTimeout(removeLine, time))
    }, removeLine = function () {
            if (line = lines.pop()[0]) line.style.opacity = 0, window.setTimeout(function () {
                line.parentNode && line.parentNode.removeChild(line)
            }, 2E3), removeInit()
        };
</script>
</body>
</html>

Последний раз редактировалось рони, 16.12.2013 в 06:02.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как работает Google Analytics: смотрю в "Инструментах разработчика" Chrome hrundel Общие вопросы Javascript 0 10.10.2013 19:31
Управление скроллом "а-ля тач" HonesT Элементы интерфейса 2 27.08.2013 14:25
Не работает JS после подгрузки div через ajax BoB AJAX и COMET 3 09.12.2011 03:03
JS не работает с AJAX...( Neonion AJAX и COMET 0 22.02.2011 17:49
запомнить переменную js в одном файле и использовать в другом. как? skalka Общие вопросы Javascript 2 28.09.2010 08:19