Пользователь
0,0
рейтинг
15 сентября 2014 в 09:45

Разработка → Сюрреализм на JavaScript. Советы по разработке на NodeJS

Привет, Хабра!

Пол года назад я подумал: «А может книгу написать?», и таки написал.



Все документы оформлены, страницы сверстаны, а тираж — отпечатан. Я не буду клянчить у вас деньги на кикстартере или предлагать что-либо купить, а вместо этого попытаюсь заинтриговать советами по разработке на NodeJS в целях пиара и привлечения внимания к книге.

Совет 1. SQL запросы лучше хранить отформатированными


SQL запросы лучше хранить отформатированными, т.к. код в этом случае гораздо проще читать и править. Т.к. SQL-запросы обычно довольно длинные, то лучше разбивать их на несколько строк, а строки в JavaScript — лучше всего выглядят в массиве.

До:
var query = "SELECT g.id, g.title, g.description, g.link, g.icon, t.id as tag_id, c.title as comment_title FROM games AS g LEFT JOIN tags AS t ON t.game_id = g.id LEFT JOIN comments AS c ON c.game_id = g.id WHERE g.id = $1";

После:
var query = [
	"SELECT ",
	"    g.id, g.title, g.description, g.link, g.icon, ",
	"    t.id as tag_id, c.title as comment_title ",
	"  FROM games AS g ",
	"    LEFT JOIN tags AS t ON  t.game_id = g.id ",
	"    LEFT JOIN comments AS c ON  c.game_id = g.id ",
	"  WHERE ",
	"    g.id = $1"
];

Согласитесь, что во втором случае запрос гораздо понятнее для читателя. Кроме того, если вы перед запросом в базу выводите запрос в консоль, то массив, прокинутый в console.dir(), опять таки гораздо понятнее, чем строка, прокинутая в console.log().



Совет 2. Жизнь становится проще, когда API различных компонентов принимает на вход любой формат


Предположим мы создали клиента к базе данных и хотим выполнить некий SQL-запрос. На входе мы ожидаем строку и параметры. Т.к. воспользовавшись прошлым советом мы решили хранить длинные запросы в массивах, то хотелось бы забыть про его преобразование в строку на каждом запросе.

До:
dataBase(query.join(""), parameters, callback);

После:
dataBase(query, parameters, callback);

Код становится проще, когда функция запроса к базе (в данном случае dataBase), сама проверяет в каком виде ей передали запрос, и если это массив — сама делает ему join().

Совет 3. Разукрасьте консоль и отформатируйте вывод информации


Дебажить программы на NodeJS трудно, т.к. очень сильно не хватает стандартной консоли разработчика со всеми фишками, типа «точек остановки». Все данные пишутся в консоль, и хочется сделать её более понятной. Если у вас нода крутится где-то на сервере, да ещё и в несколько инстансов, да ещё и несколько разных сервисов на каждой инстансе висит, а доступ вы имеете только по SSH, то консоль может реально заставить страдать.

Если в NodeJS вывести в консоль строку вида «Hello world!» с управляющими ANSI-символами, она будет окрашена в разные цвета. Пример использования управляющих ANSI-символов:



Чтобы не запоминать подобные хаки, вы можете подключить модуль colors и использовать следующий синтаксис:

console.log("Error! Parameter ID not found.".red);

Строка будет выведена красным цветом. При разработке с этим модулем вы можете раскрасить сообщения в консоли в различные цвета:
  • Красный (ошибка).
  • Желтый (предупреждение).
  • Зеленый (все хорошо).
  • Серый. Им можно выводить какие-либо параметры (например, параметры запроса), на которые можно не обращать внимания, пока не поймаете ошибку.

Консоль до цветового выделения (при быстром просмотре информация воспринимается с трудом):



Консоль после цветового выделения (при быстром просмотре информация воспринимается достаточно быстро):



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

var book = {
    console: function(message, color) {
        console.log(("Book API: " + (message || ""))[(color || white")]);
    }
}


Если все сообщения в консоли подписаны модулями, которые их отправляют, вы не только сможете сделать выборку по конкретному модулю, но и моментально найдете источник бага в критической ситуации. Форматирование текста также упрощает восприятие информации:



Таким образом, вся информация в консоли будет подписана, и вы легко сможете понять, какие события происходят в тех или иных модулях. Опять же, цветовое выделение помогает в стрессовых ситуациях, когда отказала та или иная система и нужно срочно исправить ошибку, и вчитываться в логи нет времени (я не призываю вас дебажить на продакшне, просто всякое бывает). В своих проектах я решил переписать модуль консоли, чтобы иметь возможность раскрашивать не только строки, но и массивы и объекты, а также автоматически подписывать все инстансы. Поэтому при подключении модуля я передаю ему имя пакета, которым следует подписывать сообщения. Пример использования нового модуля консоли:

var console = require("./my_console")("Scoring SDK");
console.green("Request for DataBase.");
console.grey([
    "SELECT *",
    "  FROM \"ScoringSDK__game_list\"",
    "  WHERE key = $1;"
]);

Пример вывода данных в консоль:



Совет 4. Оборачивайте все API в try/catch


У нас на работе используется фреймворк express. Каково же было мое удивление, когда я узнал, что в стандартном объекте роутера нет обертки try/catch. Например:
  1. Вы написали кривой модуль
  2. Кто-то дернул его по URL`у
  3. У вас упал сервер
  4. WTF!?


Поэтому всегда оборачивайте внешнее API модулей в try/catch. Если что-то пойдет не так, ваш кривой модуль, по крайней мере, не завалит всю систему. Та же ситуация на клиенте с шаблоном «медиатор» (его ещё называют «слушатели и публикующие»). Например:
  • Модуль А опубликовал сообщение.
  • Модули Б и В должны услышать его и отреагировать.
  • Система в цикле начинает перебирать подписчиков.
  • Модуль Б падает с ошибкой.
  • Цикл обрывается и callback-функция модуля В не вызывается.


Гораздо лучше делать перебор в try/catch и если модуль Б действительно упадет с ошибкой, то по крайней мере не убьет систему и модуль В выполнит свою работу услышав событие.

Т.к. при написании API модулей мне приходилось вновь и вновь отделять приватные и публичные методы, а после оборачивать все публичные методы в try/catch, я решил это дело автоматизировать и написал небольшой модуль для автогенерации API. Например, кидаем в него объект вида:

var a = {
	_b: function() { ... },
	_c: function() { ... },
	d:  function() { ... }
}


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

var api = {
	d: function() {
		try {
			return a.d();
		} catch(e) {
			return false;
		}
	}
};

Таким образом, я стал генерировать обертку для API всех модулей, которая в случае возникновения ошибки не пропускала её дальше. Это сделало код более стабильным, т.к. ошибка отдельного разработчика, слитая в продакшн, уже не могла уронить весь сервер со всем его функционалом.

Пример генерации API:
var a = {
	_b: function() { ... },
	_c: function() { ... },
	d:  function() { ... }
}

var api = api.create(a);

api.d(); // пример вызова


Совет 5. Собирайте запросы в конфиги


Я думаю, у каждого веб-разработчика была ситуация, когда был какой-либо жирный клиент, которому нужно было небольшое API для работы с базой данных на сервере. Пару запросов на чтение, пару на запись и ещё несколько для удаления информации. Логики в таком сервере обычно нет, и он представляет собой просто набор запросов.

Чтобы не писать каждый раз обертки для таких операций, я решил вынести все запросы в JSON, а сервер — оформить в виде небольшого модуля, который предоставляет мне API для работы с этим JSON`ом.

Пример такого модуля под express:

var fastQuery = require("./fastQuery"),
	API = fastQuery({
		scoring: {
			get: {
				query: "SELECT * FROM score LIMIT $1, $2;"
				parameters: [ "limit", "offset" ]
			},
			set: {
				query: "INSERT INTO score (user_id, score, date) VALUES ...",
				parameters: [ "id", "score" ]
			}
		},
		profile: {
			get: {
				query: "SELECT * FROM users WHERE id = $1;",
				parameters: [ "id" ]
			}
		}
	});

Наверное, вы уже догадались, что модуль будет пробегать по JSON`у и искать объекты со свойствами query и parameters. Если такие объекты будут найдены, то он создаст для них функцию, которая будет проверять параметры, ходить в базу с запросами, и посылать клиенту результат. На выходе мы получим такое API:

API.scoring.get();
API.scoring.set();
API.profile.get();

И уже его привяжем к объекту роутера:

exports.initRoutes = function (app) {
    app.get("/scoring/get", API.scoring.get);
    app.put("/scoring/set", API.scoring.set);
    app.get("/profile/get", API.profile.get);
}

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

А теперь представьте, что у вас есть ещё два серверных разработчика. Один пишет на PHP, а второй на Java. Если у вас вся серверная логика ограничивается только таким JSON`ом со списком запросов к базе, то вы можете моментально перенести/развернуть аналогичное API не только на другой машине, но и на абсолютно другом языке (при условии, что общение с клиентом стандартизировано и все общаются по REST API).

Совет 6. Выносите все в конфиги


Т.к. писать конфиги я люблю, у меня неоднократно возникала ситуация, когда у системы есть стандартные настройки, настройки для конкретного случая и настройки, возникшие в данные момент времени. Мне приходилось делать mix разных JSON объектов. Я решил выделить отдельный модуль для этих целей, а заодно добавил в него возможность брать JSON объекты из файла, т.к. хранить настройки в отдельном json-файле тоже очень удобно. Таким образом, теперь, когда мне нужно задать настройки для чего-либо я пишу:

var data = config.get("config.json", "save.json", {
	name: "Petr",
	age: 12
});

Как вы уже могли догадаться, модуль перебирает переданные ему аргументы. Если это строка — то он пытается открыть файл и прочитать настройки из него, если это объект — то он сразу пытается скрестить его с предыдущими.

В примере выше мы сначала берем некие стандартные настройки из файла config.json, потом накладываем на них сохраненные настройки из файла save.json, а потом добавляем настройки, которые актуальны в данный момент времени. На выходе мы получим mix из трех JSON объектов. Количество аргументов переданных модулю может быть любым. Например, мы можем попросить пригнать только настройки по умолчанию:

var data = config.get("config.json");


Совет 7. Работа с файлами и Модуль Social Link для СЕО


Одна из главных фич, которые мне нравятся в NodeJS, возможность работать с файлами и писать парсеры на JavaScript. При том API NodeJS предоставляет множество методов и способов для решения задач, но на практике — нужно совсем не много. За полгода активной работы с парсерами я использовал только две команды — прочитать и записать в файл. Притом, чтобы не страдать с callback-функциями и различными проблемами асинхронности, всю работу с файлами я всегда делал в синхронном режиме. Так появился небольшой модуль работы с файлами, API которого очень напоминало localStorage:

var file = requery("./utils.file.js"), // подключили модуль
	text = file.get("text.txt);        // прочитали текст в файле
	
file.set("text.txt", "Hello world!");  // записали текст в файл

На основание этого модуля работы с файлами, стали появятся другие модули. Например, модуль для СЕО. В одной из прошлых статей я уже писал, что существует огромное количество различных meta-тегов связанных с СЕО. Когда я начинал писать систему сборку для HTML приложений, СЕО я уделил особое внимание.

Суть заключается в том, что у нас есть небольшой текстовый файл с описанием сайта/приложения/игры и непосредственно HTML файл для разбора. Модуль Social Link должен найти все meta-теги связанные с СЕО в HTML файле и заполнить их. Внешнее API модуля ожидает на входе текст из файла. Это сделано для того, чтобы была возможность подключать его к системам сборки и прогонять через него текст нескольких файлов не вызывая каждый раз лишнюю процедуру чтения/записи в файл.

Например, до модуля:
<title></title>
<meta property="og:title" content=""/>
<meta name="twitter:title" content=""/>

После модуля:
<title>Некий заголовок</title>
<meta property="og:title" content="Некий заголовок"/>
<meta name="twitter:title" content="Некий заголовок"/>

Список и описание всех meta-тегов для СЕО и не только, вы можете посмотреть в книге http://bakhirev.biz/.

Совет 8. Без callback`ов жизнь проще

Многие разработчики жалуются на бесконечные цепочки callback`ов при написании сервера на NodeJS. На самом деле вы не всегда обязаны их писать и часто можно выстроить архитектуру, при которой такие цепочки будут минимальны. Рассмотрим небольшую задачу.

Задача:
Перегнать файлы с сервера А на сервер Б, получить некоторую информацию из базы данных, обновить эту информацию, отправить данные на сервер В.

Решение:
Это довольно рутинная процедура, которую мне неоднократно приходилось выполнять для решения каких-либо задач по сортировке / обработке контента. Обычно разработчики создают цикл и некую callback-функцию с методом nextFile(). Когда на очередной итерации мы вызываем nextFile(), механизм callback`ов начинается с начала, и мы обрабатываем следующий файл. Как правило, требуется в один момент времени обрабатывать только один файл и при удачном завершении процедуры переходить к обработке следующего файла. Упростить вложенность нам поможет код вида:

var locked = false,
	index = 0,
	timer = setInterval(function() {
		if(locked) return;
		locked = true;
		nextFile(index++);
	}, 1000);

Теперь мы будем раз в секунду пытаться начать обработку файла. Если программа освободится, то она выставит locked в значение false и мы сможем запустить следующий файл на обработку. Такие конструкции очень часто помогают уменьшать вложенность, распределить нагрузку по времени (т.к. очередная итерация обработки у нас запускается не чаще, чем один раз в секунду) и хоть немного сползать с бесконечных callback`ов.

Итого
Файлы с модулями можно скачать тут: http://bakhirev.biz/_node.zip (сейчас 2 часа ночи и мне лень разбираться с GitHub`ом и приводить код в человеческий вид).
Книга тут: http://bakhirev.biz/
На случай хабро-эффекта тут в PDF.

Если советы выше пришлись вам по вкусу, то хочу сразу предупредить, что книга совсем про другое. А ещё там в конце список разных умных людей, которые внесли неоценимый вклад сами того не подозревая, и которых точно следует найти и прочитать по отдельности.
@bakhirev
карма
61,5
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (36)

  • +5
    По совету 4. Надо исключение хотя бы в консоль вывести, или в лог-файл — иначе отладка модулей превращается в какой-то ужас, когда ничего не работает — и причина не видна.
    • +2
      отладка — это да, но т.к. у нас все обертки генерирует один модуль API — то и отключить все try/catch защиты во всех модулях можно с одного места. Та же самая тема с консолью — если она не нужна, то её можно перекрыть исправив только один файл.
  • +6
    По совету №4 — в продакшене достаточно запускать приложение через forever или passenger, которые в случае падения переподнимут его. Более того, при тестировании удобнее и нагляднее будет если приложение упадет. Для логирования можно использовать сторонние модули, например, тот же Winston позволяет отлавливать исключения и продолжать работу приложения (не убивая его).

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

    var module = (function() {
        var privateMethod = function() {
            // определение метода
        };
    
        return {
            publicMethod: function() {
                return privateMethod();
            }
        };
    })();
    


    По совету номер 6. В своем случае я использую стандартную систему модулей Node.js подгружая json
    // config.json
    {
        "param1": "value1",
        "param2": "value2"
    }
    
    // app.js
    
    var config = require('./config.json');
    
    config.param1 // value1
    


    Совет 8. Почему бы не использовать существующие решения async и Q (кому что нравится)?

    Вообще мне в сообществе node.js нравится тот факт, что на каждую задачу можно найти готовый модуль, решающий ее, не изобретая велосипедов (велотренажеры не в счет)
    • 0
      Дополню по поводу исключений: на своём опыте пришлось столкнуться с ситуацией когда исключение бросается в одном месте, а трейс отображается из совершенно другого модуля. так было, например, с модулем node-curl, который ловил каким-то образом эксепшен, который должен был пойматься конструкцией try-catch в совершенно другом месте кода. Описание довольно сумбурное, но и проблема тоже оказалась непростой. Для себя решил — никаких эксепшенов в ноде.
    • 0
      Каждый файл подключенный в nodejs и так оборачивается в функцию, не изобретайте велосипед. Просто объявите через var или напишите именованную функцию, а все что нужно вернуть верните через exports.
  • +2
    Поздравляю с успешным завершением этого в общем-то непростого предприятия :) Хотелось бы узнать подробности, например: сколько времени, финансов и прочих ресурсов нужно, чтобы издать что-то подобное?
    • +2
      Было бы интересно в целом в виде статьи все это почитать — от идеи до реализации.
  • 0
    А почему нельзя обойтись для первого совета просто конкатенацией строк? Читабельность запроса будет такой же. А вообще, разве в NodeJS нет никаких queryBuilder?
  • +1
    Любопытно… Интересно узнать, сколько времени и ресурсов надо, чтобы издать что-то подобное?
  • +3
    Обложку оформили — супер =)
    • +2
      Тот случай, когда хочется заиметь книгу в первую очередь из-за обложки.
      • +3
        Это пародия на Рене Магритт.
        • 0
          Спасибо, а то я долго думал, что лошадь с жокеем делают на крыше авто.
          А так я имел в виду всю обложку в 8-ми битном стиле — прямо радует и глаз и душу, побольше бы таких обложек.
  • +8
    Насчёт совета № 4 предостерегаю: употребление try…catch должно быть необыкновенно осторожным, потому что оно приводит к деоптимизации функций на движке V8 — а значит, и в Node.js.

    Простой обёртке (которая внутри себя только вызывает другой метод) деоптимизация сильно не навредит. Но если внутри try…catch расположить нечто более сложное, то неизбежны проблемы со скоростью.
  • 0
    По 8 совету, использую замечательную библиотеку bluebird, обещания рулят!
  • +8
    Совет 1. SQL запросы лучше хранить отформатированными
    Совет 2. Жизнь становится проще, когда API различных компонентов принимает на вход любой формат

    Общий совет, подойдёт к любому ЯП.

    Совет 3. Разукрасьте консоль и отформатируйте вывод информации

    Как только Вы наиграетесь с консолью и начнёте весь лог укладывать в БД, Вы откатитесь к первоначальному нечитаемому логу. Решение более сложное. В development окружении сойдёт консоль, в production — уже нужно прибивать любую раскраску.

    Совет 4. Оборачивайте все API в try/catch

    Не используйте throw в runtime и не нужно ничего оборачивать. Используйте принятый стандарт записи callback-функции. function callback(err, result).
    Совет 5. Собирайте запросы в конфиги
    Совет 6. Выносите все в конфиги

    Общий совет, подойдёт к любому ЯП.
    Совет 7. Работа с файлами и Модуль Social Link для СЕО

    Не понятно при чём здесь node.js вообще. Но вот следующее, я бы охарактеризовал как вредный совет:
    Притом, чтобы не страдать с callback-функциями и различными проблемами асинхронности, всю работу с файлами я всегда делал в синхронном режиме.

    Вы нарушаете саму идеологию асинхронного ввода/вывода, за что Вам будет больно.
    Совет 8. Без callback`ов жизнь проще

    Тоже в раздел вредных советов. Используйте callback`и. Не нравится, или говнокод получается — вас спасут promise`ы. Или не пишите на javascript, найдите другой язык… без колбеков.

    Итого:
    4 общих совета по программированию вообще. Даже не знаю зачем они, это приходит с опытом;
    1 совет так себе, буду считать, что полезный (про консоль). Вреда от него не будет;
    1 бессмысленный совет использовать try catch в асинхронном потоке исполнения ( скорее вредный );
    2 совета вредных для javascript в принципе. (синхронная работа с вводом/выводом и боязнь коллбеков);
    • 0
      7. Синхронно читать файлы — нормально, но делать это можно только во время прогрева приложения (чтение конфигов, шаблонов, чего угодно ещё что случается один раз).
      • 0
        Не спорю. Синхронная работа возможна во время первоначальной загрузки (если точнее, до первого асинхронного вызова). Так же как впрочем не страшны и throw в этот момент. Но как только приложение сделало асинхронный вызов, например, начало читать сокет, после этого всё: никаких синхронных вызовов и throw.
  • 0
    Очень много как велосипедов, так и вредных советов.

    Логи — см. пост habrahabr.ru/post/209436/. Раскраска по уровню важности — бесполезна при последующем анализе лог-файла.Нужны тэги, такие же, как и для модулей. И не забывайте, что для ошибок в unix-way надо использовать stderr.

    Конфиги — куча их готовых, см. например, minimist

    Глушить экзепшены — сказали выше

    Отказ от асинхронности — сказали выше

    Последовательное выполнение — сказали выше (async или promises).

    Пол года назад я подумал: «А может книгу написать?», и таки написал.

    А вот это действительно очень круто! :) Респект.
  • 0
    а где кнопка «помочь проекту»?
    • +2
      Тут «реверс-монетизация» :) Готов платить по рублю за каждого читателя.
      • +2
        тогда с Вас 2 рубля )

        ps
        спасибо за работу
  • 0
    По совету 8. Я бы вам посоветовал для этих целей посмотреть на стримы — весь прогрессивный мир их уже давно использует. Порой это даже более удобная высокоуровневая замена промисам.
  • +5
    Зачем вы вводите людей в заблуждение по поводу дебага nodejs?
    Во-первых: nodejs умеет работать в режиме дебага из консоли.
    Во-вторых: существует node-inspector который превращает хром в девтолзу для nodejs
    В-третьих: В WebStorm встроена хорошая поддержка дебга, со всеми плюшками.

    Блок try catch мало того что вреден для оптимизация и производительности, так он еще практически бесполезен в среде nodejs т.к. сможет отловить только синхронный код. 99.9% кода nodejs работают в асинхронном режиме, и вот их хоть тройным слоем try catch оберните, а ошибку не словите.

    Без callback`ов может и проще, но это не дает вам права советовать применять синхронные функции вместо них. Хотите синхронности пишите на пхп, хотите синхронности в javascript пишите на javascript, но не давайте своих вредных советов. Для решения проблемы вложенности придумано уже много паттернов и библиотек. Самое простое и самое удобное это Promise. Они позволяют избавиться от Большего кол-ва проблем связанного с callback`ами, в том числе большая вложенность и отлова ошибок. Вскоре Promise станет частью языка, а знание их станет таким же обязательным знанию и пониманию. Про генераторы я просто помолчу.

    В целом, книгу не читал, читать не собираюсь и если там уровень такой же как и в статье, то не советую ее читать, особенно новичкам.
    • 0
      habrahabr.ru/post/114825/ про тот инспектор. Для таких желающих про него почитать, типа меня
  • –1
    ---Совет 1. SQL запросы лучше хранить отформатированными

    Никогда и ни в каком приложении не делайте запросов к таблице из-за соображений безопасности.

    Оберните запросы во VIEW или процедуры или функцию. SELECT a, b, c FROM vTable или EXEC spProc выглядите короче из защитит от sql injection
    • 0
      Зачем так сложно? Достаточно использовать параметризованные запросы.
  • +3
    /зануда on
    Я так и не понял зачем главному исполнительному директору нужен модуль Social Link…

    И не все советы полезны, некоторые даже вредны! Особенно меня коробит то, что вы призываете отказываться от коллбеков — главной фишки асинхронности! Это не правильно. Таких вещей не нужно бояться, к ним нужно привыкать и искать как работать с ними так, чтобы было удобнее.
  • 0
    Книга супер! И стиль, и картинки. Интересный материал. Спасибо!
  • +2
    Советы так себе, скажу вам.
    • Тяжелые sql запросы следует хранить в отдельных *.sql файлах. И вообще, ребята, давно уже надо использовать es6, а там есть замечательные шаблонные литералы — и пишите себе мультилайн строки без всяких массивных хаков.
    • Это вредный совет. Если функция должна принимать на вход sql query string, так чего это мы должны разрешать какой-то array, тем более если учесть, что первый пункт отпадает. Всегда желательно что бы функция была как можно конкретнее.
    • Для дебага в консоли сойдёт, но тут ещё можно добавить группировки и различны уровни логов, как глобальные, так и групповые.
    • В ноде большинство вызовов асинхронные, какие здесь могут быть try..catch? Если инстанс падает из-за ошибки — это баг, ошибка должна логироваться, а какой нибудь процесс-менеджер должен подымать процесс.
    • Как и с первым пунктом, конфигурация не относится к коду и не должна там находиться. И вместо json лучше используйте yml, например.
    • Подходит лишь для баш скриптов.
    • Сколько можно уже мусолить тему callback-ов. Сколько же ненавистников есть, хотя ничего сложного в них нет. А совет с интервал какой-то смешной. Если уж хотите по одному файлу обрабатывать, так нужно использовать очередь, а не какой-то хак с секундным подёргиванием.
  • 0
    Вставлю свои пять копеек про try-catch, не мало уже прокомментировали, но как-то забыли про домены, которые рекомендованы быть заменой для отлова, исправления реалтайм ошибок. Кто не понимает особенностей работы try-catch и калбэков будет удивлен, почему ошибки не ловятся. Это скорее антисовет
  • 0
    А есть там что-нибудь про архитектуру crud-приложений (соц. сети и т.п.)?
  • +1
    Уже половину прочёл.
    Читается хорошо — я её открываю как сказку перед сном. Какие-то моменты читал в «Графика на JavaScript», а некоторые знал до этого, но всё равно почему-то интересно читать.
    Книга довольно сложная, не для новичков, из-за использованного словарного запаса, оборотов, резкого перехода от поверхностного описания в существенные детали.
    Но, повторюсь, читаю как сказку на ночь, интересно!

    Стал бы я её покупать? Нет, как-то не хочется. Не вижу её ценности, если открою через пол года.
  • –2
    Простите, а остальные советы в этой книге — они вот такого же примерно уровня?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.