Как стать автором
Обновить

Комментарии 34

setTimeout("feedback.send()");
НЛО прилетело и опубликовало эту надпись здесь
Поясните пожалуйста, как ваша реализация или Zone.js помогает решить проблему потери контекста? Вы в точности так же передаете в setTimeout некую функцию, которая впоследствии биндится на какой-то объект класса Context, но меня то интересует что бы её контекстом оставался feedback (из описания проблемы). Или я что то упустил?
Зона в данном случае выступает заменой контекста (в узком смысле). Для маленьких примеров такое применение кажется избыточным. Но что будет, если вместо обработчика setTimeout контекст нужно сохранять для нескольких модулей приложения и они при этом размещены в разных файлах? Моя мысль не в том, что вместо стандартных способов теперь нужно всегда использовать зоны, мысль в том, что если вы хотите хранить некое состояние в независимости от кол-ва асинхронных вызовов, зоны для этого хорошо подходят.
В таком случае в статье потеряна связь между проблемой и решением. Судя по презентации Zone.js, его прежде всего применяют для отладки, профилирования и тестирования.
нарушение неписаных правил иногда приводит к победе

Во-первых, проблемы с манкипатчингом и изменением встроенных объектов описаны давно и хорошо. Что, уже никто не помнит Prototype.js?
Во-вторых, о победе пока речи нет, команда здорово всех отпугнула, ломая API на стадии RC, релиз вышел только что и пока непонятно, взлетит или нет.

Под победой я имею ввиду инженерную победу, ведь фактически от дайджест-цикла они избавились.
Про Angular 2 говорить еще рано. В свое время с товарищем очень скептически отнеслись к Реакту. А он полетел, причем довольно высоко.
По моим оценкам, Angular 2 получился удобным и гибким. Частые изменения тоже объяснимы. В остальном время покажет.

Дайджест-цикл изначально был провальным решением. И, главное, зачем было городить этот огород? Просто чтобы не писать model.set('key', value)? Так приходилось писать $timeout(() => this.key = value), вместо явного вызова грязный хак. Так что хорошо, что избавились, конечно.


Частые изменение объяснимы, конечно, но народ, который пытался вскочить на этот поезд, был недоволен

Я сам на этом погорел. Несколько часов потратил на перевод на релизную версию. Но в итоге и правда стало лучше от изменений. И код почище. Но это субъективно все.

Еще раз: я не против изменений. Просто это создало некоторое негативное впечатление в сообществе.

Мы с пониманием на работе отнеслись. Использование предрелизной версии — подразумевает приятие ответственности за это решение. Глупо обижаться на Гугл, что они меняют API до релиза и раутер переписали три раза с нуля. На то это и цикл разработки, зато результат действительно хороший, вследствие изменений. Лучше было до релизать порешать все эти вещи, чем потом мучаться несколько лет жизненного цикла фреймворка.

Удивительный аргумент про длинные стектрейсы.


Во-первых, в длинном стектрейсе помимо важной информации содержится еще куча упоминаний самого zone.js. Не уверен что ковырять этот стек вызовов будет легче чем найти место подписки в чистом коде без зон.
Во-вторых, exception в зоне проглатывается. А это плохо, потому что ломает стандартое поведение бразуера. (Например, аналитика ошибок без дополнительных костылей собираться не будет) Да еще и неудобно для разработчика потому что флаг "pause on uncaught exceptions" в бразузере перестает работать



И это усложняет работу, потому что приходится дополнительно ловить кучу уже пойманных исколючений чтобы найти среди них свое.

Да и в целом удивительно.
Команда React борется за то, чтобы исключения в пользовательском коде не терялись во внутренностях фреймворка, чтобы инструменты отладки в браузерах работали как надо.
А в команде Angular и сопутствующих технологий пишут бразузер внутри браузера, с которым нужно научиться правильно работать, да еще и специальные иструменты для разработки использовать.

Весь кайф в том, что всем этим процессом можно управлять. Можно проглатывать исключения, а можно отправлять полные трейсы на сервер и при этом выбрасывать нативные исключения

А зачем мне управлять этим процессом, если меня устраивает стандартное браузерное поведение?


Стектрейсы на сервер отправлять я и без зон могу, вот посмотреть бы на пример того, что могут только они.

Можете оставлять браузерные ошибки, если это нужно. Zone.js довольно гибкая. Она не навязывает вам использование своих трейсов, она предоставляет информацию. Как и когда эту информацию использовать решайте сами. Вот пример. Писал быстро, возможны ошибки в фильтрации, но в целом идея должна быть понятна.

Проблема в вашем примере в том, что если выбрасывать ошибку наружу, то браузер остановится где-то в зоне, где она бросает ошибку наружу, а не на оригинальном месте, как ожидалось

Я здесь не вижу большой проблемы. Да, чтобы управлять ошибками, нужно их сначала перехватить, а потом бросить опять. Лично мне это не мешает отлаживать.

Проблема в том, что браузер останавливается где-то внутри кода zone.js, а не вашем. Пользы от этого немного, ведь причины остановки не понять.


Как я воспроизвожу баг пользователя:


Открываю отладчик, ставлю флаг, чтобы останавливался на всех непойманных исключениях. Затем проделываю какие-то действия. Если случилось исключение, браузер останавливается на этой строке, сразу в контексте, со всеми переменными из замыкания. Можно смотреть значения и разбираться, что здесь не так.


До этого у меня был опыт работы с Angular 1, где все исключения проглатыавались как и в zone. Там приходилось долго копать до настоящего места с ошибкой, и меня это всегда расстраивало.


В общем, мой пойнт в том, что проглатывать исключения — это плохо. Плюсов, кроме абстрактного "зато все гибко", вы так и не привели, а неудобства налицо.

Вы так хотели отлаживать? У меня вроде как завелось.

Имменно так, только со снятой галочкой "pause on caught exceptions".


Потому что если ее включить, то в консоль посыпется очень много лишнего

Вы взяли один кейс использования библиотеки, помимо трейсов у нее есть и другие применения. Цель статьи не в том, чтобы продать вам Zone.js или Angular 2. Цель статьи разобраться в том, как работает технология внутри.
НЛО прилетело и опубликовало эту надпись здесь
А чем bind плох?
 В IE6 не работает
НЛО прилетело и опубликовало эту надпись здесь

А у вашего callback даже метода call нету. Но почему-то это недостатком не считается...

НЛО прилетело и опубликовало эту надпись здесь

У вас производительность убивается объектом arguments. Если старые браузеры не важны, можно сделать так:


function callCallback(callback, ...args) {
    return callback.fn.apply(callback.context, args);
}

Но, вообще говоря, невозможность замены контекста обычно рассматривается как достоинство, а не недостаток. Так что bind прекрасно решает большинство задач.

Можно еще в функциях объекта использовать self или that, а сам объект при этом создавать через анонимный конструктор:
var feedback = new function(){
    var self = this;
    this.message = 'Привет!';
    this.send = function () {
        alert(self.message);
    }
};

Получается конечно не так компактно, но, имхо, лучше, чем использовать специальный объект для трекинга контекста…

И конкретно в этом примере, раз уж объект через объявлен через var, то можно еще и так:
var feedback = {
    message: 'Привет!',
    send: function () {
        alert(feedback.message)
    }
}
Понятно, что удобно, но нельзя было ее форкнуть и воткнуть внутрь библиотеки, как они сделали с JQuery в первой версии и чтобы мы вообще не догадывались про ее существование?
А в чем связь зон и отсутствие dirty checking-а? Зоны — это же просто прозрачная замена для всяких $timeout, $interval и тд. А то, что теперь есть change detector однонаправленный, это как бы про другое.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий