Pull to refresh

Comments 9

Мейл.ру, у вас такие хорошие технические статьи, что начинает вериться в превращение в корпорацию бобра.

Но потом всё снова встаёт на свои места :( Может быть здесь вы расскажете: что за ерунда творится с м-агентом?
И наконец, если вам нужно убрать прослушивателя, то воспользуйтесь методом removeListener.

каким методом воспользоваться, чтобы агент не сообщал постоянно, что хочет обновиться?

ваши пользователи уже дошли до такого http://forum.oszone.net/thread-326927-3.html
Когда разработчик хочет сделать больно
Запрет автоматического обновления Mail.Ru агента до версии 10
1) Сносим все установленные версии Mail.Ru агента унинстайлером, например Geek Uninstaller
2) создаём пустую папку c:\Users\имя пользователя\AppData\Roaming\Mail.Ru\Agent\bin (нужно иметь доступ к скрытым системным папкам)
3) запрещаем все права NTFS всем группам и пользователям созданной папке bin
4) установливаем, запускаем Mail.RU Agent и настраеваем свой профиль, например Mail.RU Agent 6.5.9316 RePack (& Portable) by elchupacabra (проверено на этой версии) скачать можно тут https://nnmclub.to/forum/viewtopic.php?t=906161
5) ждём некоторое время, в папке c:\Users\имя пользователя\AppData\Roaming\Mra\Update
появляется установочный файл новой версии magentsetup.exe и файл version4.txt
6) закрываем Mail.RU Agent
7) в файле version4.txt меняем значение 1 на 0
20056 magentsetup.exe 249003180 1 http://mra.mail.ru/update/update9.html silent_update:1 'Новый Агент 6.5!'
меняем на
20056 magentsetup.exe 249003180 0 http://mra.mail.ru/update/update9.html silent_update:0 'Новый Агент 6.5!'
8) запрещаем только запись, правами NTFS всем группам и пользователям version4.txt
9) установочный файл c:\Users\имя пользователя\AppData\Roaming\Mra\Update\magentsetup.exe
файл заменяем пустым файлом magentsetup.exe (создаём пустой текстовый файл, потом преименовываем его в исполняемый exe)
10) запрещаем права NTFS созданному файлу magentsetup.exe
11) включаем Mail.RU Agent и пользуемся

प्रथम दूसरा

Это перевод статьи на хинди?
Для работы с EventEmitter нужно создать расширяющий его класс.

И далее по тексту


class WithLog extends EventEmitter {
  execute(taskFunc) {
    console.log('Before executing');
    this.emit('begin');
    taskFunc();
    this.emit('end');
    console.log('After executing');
  }
}

Этот пример нарушает "S" и "I" из SOLID и создаёт наивысшую связанность.


Для достижения большей гибкости кода лучше избегать расширения стандартных классов.


Во-первых всегда можно сделать импиративно:


const emitter = new EventEmitter();
emitter.emit('begin');
taskFunc();
emitter.emit('end');

Такой код легко читать и легко менять. Минус такого кода в том что он выглядет "не круто".


Если уж не терпится создать класс для повторного использования кода, то лучше помнить мантру делигирование — лучшая альтернатива наследованию:


class WithLog {
  constructor(emitter) {
    this.emitter = emitter;
  }

  execute(taskFunc) {
    console.log('Before executing');
    this.emitter.emit('begin');
    taskFunc();
    this.emitter.emit('end');
    console.log('After executing');
  }
}

const withLog = new WithLog(new EventEmitter());
withLog.execute();

Оператор new несёт гораздо меньше потенциального вреда и рисков полного рефакторинга чем оператор extend.


Такие дела.

Хотя я с вами согласен, но мне кажется что статья не об этом.
Если в каждую статью вмещать всевозможные best practise, то это может отвлекать внимание от того, о чем статья.

Как бы EventEmitter был создан именно для того, чтобы от него можно было наследоваться.

Да, официальная документация предлагает наследование, но я не увидел в этом никаких преимуществ. Уж простите дурака. Может проясните зачем оно нужно?

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

Во-первых вказано “Создавайте такие хост-функции, которые принимают коллбэки либо всегда синхронно, либо всегда асинхронно” а про dezalgo не сказано. http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
Ну а во-вторых, автор допустил ошибку в своей “универсальной” функции


readFileAsArray = function(file, cb = () => {})

Сразу бросилось в глаза значение cb по-умолчанию. И не зря. Потому что в случае когда
1) readFileAsArray принимает колбэк и не использует возвращаемый промис и
2) fs.readFile возвращает ошибку
то срабатывает reject(err), не ловится и вызывает unhandledRejection, что в дальнейшем в статье и происходит


UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: ENOENT: no such file or directory, open

а автор похоже не понимает почему. Уверен, что значение по-умолчанию надо от cb убрать, а тело должно проверять ее наличие


    fs.readFile(file, function(err, data) {
      if (err) {
        if (!cb) return reject(err);
        return cb(err);
      }
      const lines = data.toString().trim().split('\n');
      if (!cb) return resolve(lines);
      cb(null, lines);
    });

Да проще можно. Если уж обещание все равно создается в любом случае — надо его и использовать.


var result = new Promise((resolve, reject) => {
  // ...
});
if (cb) result.then(lines => cb(null, lines), cb);
return result;
Sign up to leave a comment.