Если у вас есть эти привычки, вы должны попытаться исправить их

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

Вместе в этой статье мы рассмотрим 3 самые распространенные вредные привычки, которых следует остерегаться.

1. Неточное понимание асинхронного кода 😵‍💫

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

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

Итак, важно понимать цикл событий и то, как использовать обратные вызовы, промисы и асинхронность/ожидание для обработки асинхронного кода.

а) Использование обратных вызовов:

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

function fetchData(callback) {
  // fetch data from server
  // when data is ready, call the callback function with the data
  callback(data);
}

fetchData(function(data) {
  // do something with data
});

b) Использование промисов

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

function fetchData() {
  return new Promise((resolve, reject) => {
    // fetch data from server
    if (data) {
      resolve(data); // data is ready
    } else {
      reject("Error"); // there was an error
    }
  });
}

fetchData()
  .then((data) => {
    // do something with data
  })
  .catch((error) => {
    // handle the error
  });

c) Использование Async/Await

Async/await — это более новый способ написания асинхронного кода в JavaScript. Он обеспечивает более синхронный способ написания асинхронного кода, упрощая его чтение и запись.

async function fetchData() {
  // fetch data from server
  if (data) {
    return data; // data is ready
  } else {
    throw "Error"; // there was an error
  }
}

async function main() {
  try {
    const data = await fetchData();
    // do something with data
  } catch (error) {
    // handle the error
  }
}

main();

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

2. Код не оптимизируется🦦

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

а) Кэширование

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

Вот несколько примеров того, как реализовать кэширование в Javascript:

— Кэширование браузера с использованием заголовка Cache-Control

const response = await fetch('data.json', {
  headers: { 'Cache-Control': 'max-age=3600' }
});
const data = await response.json();

В этом примере после получения данных с сервера с помощью функции fetch() мы используем заголовок Cache-Control, чтобы указать, что данные должны кэшироваться в течение 1 часа (3600 секунд).
Если данные снова запрашиваются в течение следующего часа, браузер будет обслуживать его из кеша вместо того, чтобы делать другой запрос на сервер.

Кэширование Service Worker с помощью Cache API

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => response || fetch(event.request))
  );
});

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('my-cache')
      .then(cache => cache.addAll([
        'index.html',
        'style.css',
        'script.js'
      ]))
  );
});

В этом примере сервисный работник используется для кэширования ресурсов, когда пользователь посещает веб-сайт. Событие fetch используется для перехвата всех сетевых запросов, а событие Cache API используется для кэширования ответов. Если кэшированный ответ доступен, он возвращается; в противном случае делается запрос к серверу.
Более точную документацию по этому поводу вы можете найти здесь!

Кэширование в памяти с использованием объекта JavaScript

const cache = {};

function getData(key) {
  if (cache[key]) {
    console.log('Data served from cache');
    return Promise.resolve(cache[key]);
  }
  return fetch(`/data/${key}.json`)
    .then(response => response.json())
    .then(data => {
      cache[key] = data;
      console.log('Data served from server');
      return data;
    });
}

В этом примере кэш в памяти используется для хранения данных, полученных с сервера. Когда вызывается функция getData(), она проверяет, доступны ли данные в кеше. Если это так, функция возвращает данные из кеша; в противном случае он извлекает данные с сервера и сохраняет их в кэше для будущего использования.

б) Ленивая загрузка

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

Использование атрибута loading

<img src="placeholder.jpg" data-src="image.jpg" loading="lazy" alt="Lazy loaded image">

Атрибут loading имеет значение lazy, что указывает браузеру отложить загрузку изображения до тех пор, пока оно не понадобится. Когда изображение находится в области просмотра, браузер загрузит его и заменит атрибут src атрибутом data-src.

Использование динамического импорта

const button = document.querySelector('button');

button.addEventListener('click', async () => {
  const module = await import('./module.js');
  module.doSomething();
});

Ключевое слово await используется для ожидания загрузки модуля перед вызовом его метода doSomething(). Таким образом, модуль не загружается до тех пор, пока он не потребуется при нажатии кнопки, что может сократить время начальной загрузки страницы.

— Использование Intersection Observer API

<div class="lazy-load" data-src="content.html"></div>
const lazyLoad = document.querySelectorAll('.lazy-load');

const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const content = entry.target;
      const src = content.getAttribute('data-src');
      fetch(src)
        .then(response => response.text())
        .then(html => {
          content.innerHTML = html;
          observer.unobserve(content);
        });
    }
  });
});

lazyLoad.forEach(content => {
  observer.observe(content);
});

Intersection Observer API используется для ленивой загрузки контента, когда он находится в области просмотра. Атрибут data-src используется для хранения URL-адреса контента, который будет загружаться отложенно. Когда контент находится в области просмотра, функция fetch() используется для загрузки контента, а свойство innerHTML используется для его добавления на страницу. После загрузки содержимого метод observer.unobserve() используется для прекращения наблюдения за содержимым, что может повысить производительность.

c) Оптимизация циклов

Циклы могут быть распространенным источником проблем с производительностью, особенно когда они вложены друг в друга или имеют большое количество итераций. Вы можете использовать такие методы, как кэширование длины цикла, использование методов массива, таких как map() и reduce() вместо for loops, или избегать ненужных итераций, чтобы оптимизировать циклы и повысить производительность.

Цикл for вместо цикла for…in

const arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

Это более эффективно, чем использование цикла for...in, который предназначен для перебора свойств объекта.

Цикл while вместо цикла do…while

let i = 0;
while (i < 1000000) {
  console.log(i);
  i++;
}

Это более эффективно, чем использование цикла do...while, который всегда выполняет тело цикла хотя бы один раз.

Метод Array.from() для создания массива из итерируемого объекта

const set = new Set([1, 2, 3, 4, 5]);
const arr = Array.from(set);
console.log(arr); // [1, 2, 3, 4, 5]

Метод Array.from() используется для создания массива из Set. Это более эффективно, чем использование цикла for...of или метода Array.prototype.slice.call().

3. Неправильная обработка ошибок 🚧

Игнорирование ошибок или неправильная их обработка могут привести к неожиданному поведению или даже к сбоям. Разработчики всегда должны использовать блоки try/catch или функции обработки ошибок для обработки ошибок и предотвращения их дальнейшего распространения.

Ниже приведены некоторые распространенные «необработанные ошибки»:

Игнорирование возвращаемого значения функции, которая может вызвать ошибку

function fetchData() {
  // some code that may throw an error
}

const data = fetchData();
// continue with code assuming data was successfully fetched

Проглатывание ошибок путем регистрации и продолжения выполнения

try {
  // some code that may throw an error
} catch (e) {
  console.log(e);
  // continue with code assuming no error occurred
}

Не используются правильные сообщения об ошибках

— Отсутствие перехвата исключений в блоке try-catch

Выводы 🎯

Это лишь некоторые из наиболее распространенных вредных привычек разработчиков.
Спасибо, что зашли так далеко, и если у вас есть какие-либо другие вредные привычки, которые постоянно совершают разработчики, сообщите мне об этом в комментариях.

Если вам понравилась эта статья, не стесняйтесь нажимать кнопку 👏 столько раз, сколько хотите, это будет стимулировать меня к написанию других статей :)

Дополнительные материалы на PlainEnglish.io.

Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .