Pull to refresh
15
0
Дмитрий Беляев @bingo347

Разработчик Rust

Send message
Вы описали патерн «шина событий», известный давно, и имеющий ряд недостатков:
1. связанность. Да-да, именно она. Для того, чтобы слушать событие, мне нужно знать его имя, как следствие слушатель уже что-то знает об отправителе.
2. отсутствие контроля. Без дополнительных абстракций вещать может кто угодно и что угодно. Если модуль А и модуль Б назовут свои события одинаково, будет конфликт.
3. хаос потока исполнения. В идеальном мире модули общаются только через шину событий. Неоднократно в проектах реализующих данный патерн натыкался на ситуации, когда одно событие порождает множество других. Это очень сложно отлаживать, особенно если некое событие отправляется из нескольких мест.

Поставленную задачу низкой связанности гораздо лучше решает связка патернов «машина состояний» (redux) и «наблюдатель» (rx.js)
Я вижу две, на мой взгляд, серьезные проблемы в данном подходе, которые делают его нежелательным для использования на продакшене:
1. Сборка шаблонов в рантайме. Это черевато проблемами с производительностью. Если правильно понял принятое решение, на клиент грузится несжатый исходник шаблона, что приводит к передаче лишних данных по сети. После исходник компилируется, что тратит ресурсы клиента.
2. Отсутствует проверка шаблона на ошибки. Любой незакрытый тег, отсутствующая переменная или метод просто уронят компонент.

Сама идея подгружать шаблоны, или даже компоненты целиком, очень даже стоящая. Но все таки должна быть сборка, которая как уменьшит объем загружаемых на клиент данных, так и может выявить ошибки в шаблоне до попадания в продакшн.

Так же вангую еще и третью проблему: системы контроля версий не используются, на сколько понял файлы шаблонов просто заливаются на сервер (ftp, scp, samba, rsync — не важно, они все ненадежны для выкладывания на продакшн). Нет разрешения конфликтов, нет возможности быстро откатится, нет истории правок, сложно автоматизировать сборку.
Арч не очень то хороший выбор, имхо. Приходилось мне с ним мучиться пару месяцев, может сказалось конечно, что всю жизнь на debian-based дистрах, но пакман с его репозиториями меня добил, всегда самое свежее и без вариантов, убить систему обновлением гораздо проще чем на debian sid… А если хочешь LTS версию какой то софтины приходится лезть в AUR, в котором все из исходников собирается, только чем это лучше гентушного emerge? — да ничем, emerge гибче гораздо
В листинге, где описывается функция waitForOpacity первый раз лишняя точка с запятой
Есть одни распиареные курсы, находящиеся под крылом у крупного российского гиганта, сколько кандидатов после этих курсов приходило на собеседование, в лучшем случае полный ноль
Вообще-то это норма русского языка
Хорошо было бы добавить возможность мокать встроенные модули ноды, то есть вместо реального fs отдать например Proxy от него, в котором пускаем модуль только к функциям чтения

Также в текущей реализации вижу проблему внедрения данного решения в существующие проекты, придется править практически всю кодовую базу проекта, патчинг require в одном месте тут выглядит более привлекательным

Ну и напоследок, допустим Ваш пакет станет очень популярным, Вы можете дать гарантии, что пакет достаточно защищен от атак злоумышленников?
методы не реактивны, их возвращаемое значение можно вставить в шаблон
стрелочная функция еще не имеет своей arguments, а наследует его из замыкания
За много лет работы с JS ни разу не было проблем с this, более того в умелых руках это очень мощный инструмент языка, а проблемы описанные в статье говорят лишь о том, что автор не умеет и не понимает JavaScript…

Теперь подумайте вот о чем:
1. На каждый экземпляр объекта созданного таким образом будут создаваться новые функции-методы. Это засоряет память, это убивает оптимизацию
Функции в js компилируются в момент первого вызова и оптимизируются при нескольких последующих вызовах. В случае Вашего подхода это будет делаться для каждого инстанса, что дорого, очень
Если же использовать правильный подход с прототипами функции будут созданы и скомпилированы только 1 раз, все инстансы будут использовать одну и ту же функцию. Мы экономим память. Инстанс создается быстрее. Инстанс работает быстрее, когда его методы уже скомпилированы при работе с предыдущим инстансом.
2. Как быть с наследованием? Допустим я хочу на базе Вашего двухсвязного списка сделать список с произвольным доступом на чтение и возможностью итерации. Если бы были прототипы — я бы относледовался от Вашего прототипа и добавил бы необходимые мне методы, но Ваш код я не смогу переиспользовать, это плохо

У меня одного плохо сочетается понятие "реалтайм" с тормозами socket.io?

Оптимизатор v8 сам умеет чекать «чистые» функции и применять к ним мемоизацию, притом с гораздо более умным кэшем, из которого со временем удаляются редко используемые значения, освобождая тем самым память
подобные оптимизации — пережиток далекого прошлого
более того, подобная «оптимизация» может даже замедлить код
Почему вы хотите присоединиться к компании «Apple» и от каких преимуществ со своей нынешней работы вы откажетесь, если мы наймем вас?

Моя репутация разработчика для меня дороже, чем работа в распиаренном бренде типа Apple, который производит низкокачественный софт, но если меня все таки примут, то примерно через год браузер сафари наконец то будет соответствовать веб-стандартам
я не ставлю адблок принципиально по одной причине, я предпочитаю посмотреть таргетинговую рекламу, среди которой, кстати, встречается полезная, чем всякое УГ, вроде увеличения груди, проплатившее адблоку
Опыт использования блокировщиков у меня лично такой…
Образование идет не вслед за спросом, а, к сожалению, вслед за продажными чиновниками… И ставит то что сверху прислали, а иначе оштрафуют
node v8.0.0

это где такую взять? на офф сайте только 6.9.4 и 7.4.0 на текущий момент
Провел тесты на node v6.9.4 v8 v5.1.281.89

Исходники тестов:
'use strict';

function tryCatch() {
  try {
    return null;
  } catch(e) {
    return e;
  }
}
checkOptimizationStatus(tryCatch);

function forOf() {
  var r = 0, a = [1,2,3];
  for(var e of a) r += e;
  return r;
}
checkOptimizationStatus(forOf);

function forIn() {
  var r = 0, a = {1:1, 2:2, 3:3};
  for(var e in a) if(a.hasOwnProperty(e)) r += a[e];
  return r;
}
checkOptimizationStatus(forIn);

function constDecl() {
  const a = 5;
  return a;
}
checkOptimizationStatus(constDecl);

function letDecl() {
  let a = 5;
  return a;
}
checkOptimizationStatus(letDecl);

function argsRest(...args) {
  return args;
}
checkOptimizationStatus(argsRest);

function argumentsRewrite(a) {
  a = a || 5;
  return a;
}
checkOptimizationStatus(argumentsRewrite);

function argumentsLeak1() {
  return arguments;
}
checkOptimizationStatus(argumentsLeak1);

function argumentsLeak2() {
  return Array.prototype.slice.call(arguments);
}
checkOptimizationStatus(argumentsLeak2);

function argumentsLeakToSecondArgOfApply() {
  return Array.prototype.concat.apply([], arguments);
}
checkOptimizationStatus(argumentsLeakToSecondArgOfApply);

function defaultArguments(a, b = 5) {
  return a + b;
}
checkOptimizationStatus(defaultArguments);

function arrayDestruct() {
  const [a, b, c] = [1, 2, 3];
  return a + b + c;
}
checkOptimizationStatus(arrayDestruct);

function objectDestruct() {
  const {a, b, c} = {a: 1, b: 2, c: 3};
  return a + b + c;
}
checkOptimizationStatus(objectDestruct);

function* generatorSimple() {
  yield 1;
  yield 2;
  yield 3;
}
checkOptimizationStatus(generatorSimple);

function* generatorInfinity() {
  var i = 0;
  while(true) yield i++;
}
checkOptimizationStatus(generatorInfinity);

function infinityLoop(n = 10) {
  var a = false;
  while(true) {
    if(a) break;
    if(n-- === 0) a = true;
  }
}
checkOptimizationStatus(infinityLoop);

function containsObjectLiteralWithProto() {
  return {__proto__: String.prototype};
}
checkOptimizationStatus(containsObjectLiteralWithProto);

function containsObjectLiteralWithGetter() {
  return {
    get prop() {
      return 3;
    }
  };
}
checkOptimizationStatus(containsObjectLiteralWithGetter);

function containsObjectLiteralWithSetter() {
  return {
    set prop(val) {
      this.val = val;
    }
  };
}
checkOptimizationStatus(containsObjectLiteralWithSetter);

class ClassStatic {
  static classStaticMethod() {}
}
checkOptimizationStatus(ClassStatic.classStaticMethod);

class ClassConstructor {
  constructor() {}
}
checkOptimizationStatus(ClassConstructor, true);


Чекер:
function checkOptimizationStatus(fn, withNew = false) {
  if(withNew) {
    new fn();
    new fn();
    %OptimizeFunctionOnNextCall(fn);
    new fn();
  } else {
    fn();
    fn();
    %OptimizeFunctionOnNextCall(fn);
    fn();
  }

  switch (%GetOptimizationStatus(fn)) {
    case 1: console.log(fn.name, 'Function is optimized'); break;
    case 2: console.log(fn.name, 'Function is not optimized'); break;
    case 3: console.log(fn.name, 'Function is always optimized'); break;
    case 4: console.log(fn.name, 'Function is never optimized'); break;
    case 6: console.log(fn.name, 'Function is maybe deoptimized'); break;
    case 7: console.log(fn.name, 'Function is optimized by TurboFan'); break;
    default: console.log(fn.name, 'Unknown optimization status'); break;
  }
}


Результат:
tryCatch Function is not optimized
forOf Function is not optimized
forIn Function is optimized
constDecl Function is optimized
letDecl Function is optimized
argsRest Function is optimized by TurboFan
argumentsRewrite Function is optimized
argumentsLeak1 Function is not optimized
argumentsLeak2 Function is not optimized
argumentsLeakToSecondArgOfApply Function is optimized
defaultArguments Function is optimized
arrayDestruct Function is not optimized
objectDestruct Function is optimized
generatorSimple Function is not optimized
generatorInfinity Function is not optimized
infinityLoop Function is optimized
containsObjectLiteralWithProto Function is not optimized
containsObjectLiteralWithGetter Function is not optimized
containsObjectLiteralWithSetter Function is not optimized
classStaticMethod Function is optimized
ClassConstructor Function is optimized
Довольно новый и небольшое сообщество. Не стал его рассматривать. Но со временем все может быть.

Go ровесник node.js, оба появились в 2009
У обоих развитое комьюнити
Так что странно упомянуть один и упустить другой
Фронтендеры авито настолько боятся показать свою некомпетентность, спалив свой кривой код, что даже суют вирус в расширения хрома при попытке открыть devtools на их сайте, судя по предоставленному в статье интервью не зря…
все что можно сделать в node.js — можно и в electron, в том числе и работать с БД

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Date of birth
Registered
Activity

Specialization

Backend Developer, Fullstack Developer
Lead