Грешка първа: блокиране на цикъла на събитието


грешки

Въпреки това, част от кода, която заема процесора, може да блокира цикъла на събитията, принуждавайки хиляди свързани клиенти да изчакат изпълнението им да завърши. Пример за такъв код е опит за сортиране на много голям масив:


Извикването на функцията sortUsersByAge е малко вероятно да създаде проблеми с малък масив. Но когато работите с голям масив, това драстично ще намали цялостната производителност. Проблеми може да не възникнат, ако операцията е крайно необходима и сте сигурни, че никой друг не чака цикъла на събитието (да речем, ако правите инструмент за команден ред и не е необходимо да изпълнявате асинхронно). Но за сървър Node.js, обслужващ хиляди клиенти едновременно, този подход не е валиден. Ако този масив от потребители се извлече директно от базата данни, тогава най-доброто решение би било да се извлече вече сортиран. Ако цикълът на събитията е блокиран от цикъла за изчисляване на общия резултат от голям брой финансови транзакции, тогава тази работа може да бъде делегирана на някой външен изпълнител, за да не блокира цикъла на събитието.

За съжаление за този тип проблеми няма сребърен куршум и всеки случай изисква индивидуален подход. Основното нещо е да не претоварвате процесора като част от изпълнението на екземпляр Node.js, който работи паралелно с няколко клиента.

За да избегнете тази грешка, достатъчно е да сте бдителни. Някои разработчици са взели за правило да добавяте ключовата дума „return“ преди всяко обаждане с обратно извикване:


В много асинхронни функции възвръщаемата стойност не е важна, така че този подход често избягва извикването на обратно повикване няколко пъти.

Този проблем често се нарича "Ад за обратно обаждане". Макар че това не е грешка сама по себе си, тя може да накара кода бързо да излезе извън контрол:


разработване


Когато се извика функцията „testTimeout“, първо ще се покаже „Begin“, след това „Waitng“ и след около секунда - „Done!“. Ако трябва да се направи нещо след извикване на обратното повикване, то то трябва да бъде извикано в самия обратно повикване.

Node.js третира всеки файл като малък изолиран модул. Да приемем, че вашият пакет съдържа два файла a.js и b.js. За да може b.js да има достъп до функционалност от a.js, последният трябва да експортира тази функционалност, като добави свойства към обекта "износ":


Ако това бъде направено, всяка заявка за a.js ще върне обект с функцията verifyPassword в свойства:


Ами ако трябва да експортираме тази функция директно, а не като свойство на някакъв обект? Можем да направим това, като заменим променливата "износ", но най-важното е да не я наричаме глобална променлива:


Забележете износа като свойство на обекта на модула. Разликата между „module.exports“ и „export“ е много голяма и неразбирането на това води до объркване за начинаещите разработчици на Node.js.


Въпреки това, в случаите на асинхронно изпълнение, try-catch няма да работи както очаквате. Например, ако се опитате да защитите впечатляващо парче код с множество асинхронни сегменти с голям блок за опит за улавяне, тогава може да не работи:


Ако обратното повикване, предадено на „db.User.get“, се извика асинхронно, тогава блокът try-catch няма да може да улови грешките, генерирани в callback, тъй като ще бъде изпълнен в различен контекст от контекста try-catch . Грешките в Node.js могат да се обработват по различни начини, но трябва да се придържате към един и същ шаблон за аргументите на всички функции за обратно извикване (грешка, ...) - първият аргумент във всяко обратно извикване трябва да очаква грешка, ако се появи.


Въпреки това, за разлика от аритметиката, побитовите оператори и операторите на смяна работят само върху последните 32 бита на такива големи "цели числа". Например, ако преместите „Math.pow (2, 53)“ с 1, резултатът винаги ще бъде 0. Ако използвате побитово ИЛИ, то също ще бъде 0.


Шансовете са, че рядко срещате големи числа, но когато това се случи, разгледайте една от многото библиотеки, които правят точна математика на големи числа. Например node-bigint.

Да приемем, че трябва да създадете малък прокси сървър, който обработва отговорите, когато поискате някои данни от друг сървър. Да кажем да работим с изображения с Gravatar:


В този пример вземаме изображение от Gravatar, четем го в буфера и го изпращаме като отговор на заявка. Не е лошо оформление, тъй като тези изображения са малки. Какво ще стане, ако имате нужда от прокси гигабайт съдържание? По-добре да използвате този метод:


Тук вземаме изображение и просто го излъчваме като отговор на клиента, без да четем цялото в буфера.


За да активирате режима за отстраняване на грешки, просто стартирайте този код, като зададете променливата на средата DEBUG на „app“ или „*“:

Независимо дали вашият код работи в производствена или във вашата локална среда, силно се препоръчва да използвате диспечерска програма. Много опитни разработчици смятат, че кодът трябва бързо да се срине. Ако възникне неочаквана грешка, не се опитвайте да се справите с нея, оставете програмата да се срине, така че диспечерът да я рестартира в рамките на няколко секунди. Разбира се, това далеч не е всичко, което диспечерите могат да направят. Например можете да конфигурирате програмата да се рестартира, ако се променят някои файлове, и много повече. Това значително опростява процеса на разработка в Node.js. Следните диспечери могат да бъдат посъветвани:

  • pm2
  • завинаги
  • нодемон
  • ръководител

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

Можете да помогнете и да прехвърлите някои средства за разработването на сайта