Базовый курс JavaScript
-
1) console.log(), Переменные
-
2) Типы данных, Операторы
-
3) Условные конструкции
-
4) Объекты, массивы
-
5) Циклы
-
6) Функции. Диалоговые окна
-
7) Результат функции. Стрелочная фукция
-
8) callback, find, filter
-
9) Введение в методы и свойства
-
10) Методы строк и чисел
-
11) Методы массивов
-
12) Работа с DOM
-
13) Элементы,HTMLCollection и NodeList
-
14) Создание, добавление, замена и удаление элементов. Управление атрибутами элементов. Свойство className
-
15) addEventListener()
-
16) window, event
-
17) Работа с формами
-
18) Таймеры. this
-
JSON
-
19) Обработка ошибок
-
20) JSON, Promise, async и await
-
21) callBack()
-
22) fetch
-
7) Взаимодействие с DOM (Document Object Model)
-
23) LocalStorage, sessionStorage
21) callBack()
Callback в JavaScript — это функция, переданная в другую функцию в качестве аргумента, которая затем вызывается по завершении определённой операции.
function fetchData(callback) {
setTimeout(() => {
const data = { id: 1, name: "John" };
callback(data); // Вызов callback с результатом
}, 1000); // Симуляция задержки
}
function processData(data) {
console.log("Полученные данные:", data);
}
fetchData(processData); // Передаём processData как callback
Алгоритм:
- Передаём функцию
processDataкак аргумент. fetchDataвызывает её после получения данных.
Преимущества:
- Удобно для асинхронных операций.
Недостатки:
- «Callback Hell» — вложенность при сложных цепочках.
Для избежания сложности используют Promises или async/await.
Callback Hell
Callback Hell — это ситуация, когда в коде появляется много вложенных callback-функций, что делает его трудно читаемым и сложным для поддержки.
Пример Callback Hell:
function fetchData(callback) {
setTimeout(() => {
console.log("Данные загружены");
callback();
}, 1000);
}
function processData(callback) {
setTimeout(() => {
console.log("Данные обработаны");
callback();
}, 1000);
}
function saveData(callback) {
setTimeout(() => {
console.log("Данные сохранены");
callback();
}, 1000);
}
// Вызов функций с вложенными callback'ами
fetchData(() => {
processData(() => {
saveData(() => {
console.log("Вся операция завершена");
});
});
});
Почему это плохо?
- Плохая читаемость: код становится сложным из-за большой вложенности.
- Сложность отладки: ошибки трудно отследить.
- Трудность в изменении: добавление новых функций ухудшает структуру.
Решение Callback Hell:
Использование Promises:
function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Данные загружены");
resolve();
}, 1000);
});
}
function processData() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Данные обработаны");
resolve();
}, 1000);
});
}
function saveData() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Данные сохранены");
resolve();
}, 1000);
});
}
fetchData()
.then(processData)
.then(saveData)
.then(() => {
console.log("Вся операция завершена");
});
Использование async/await:
async function main() {
await fetchData();
await processData();
await saveData();
console.log("Вся операция завершена");
}
main();
Promises
Promises (промисы) в JavaScript — это объект для работы с асинхронными операциями. Они позволяют писать более удобный и читаемый код по сравнению с колбэками.
Основные состояния Promise:
- Pending (в ожидании) — операция ещё не завершена.
- Fulfilled (выполнено) — операция успешно завершена.
- Rejected (отклонено) — операция завершилась с ошибкой.
//Создание Promise:
const promise = new Promise((resolve, reject) => {
const success = true; // Условие выполнения
if (success) {
resolve("Операция выполнена успешно!"); // Успешное завершение
} else {
reject("Ошибка выполнения!"); // Завершение с ошибкой
}
});
// Обработка результата
promise
.then(result => {
console.log(result); // Если resolve
})
.catch(error => {
console.error(error); // Если reject
});
Пример: асинхронная операция
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { id: 1, name: "John" };
if (data) {
resolve(data); // Успех
} else {
reject("Ошибка загрузки данных"); // Ошибка
}
}, 1000); // Симуляция задержки
});
}
fetchData()
.then(data => console.log("Данные:", data)) // Успешно
.catch(error => console.error("Ошибка:", error)); // Ошибка
Преимущества Promises:
- Читаемость кода.
- Устранение «Callback Hell».
- Удобная обработка ошибок.
Комбинация с async/await:
async function fetchData() {
try {
const data = await new Promise(resolve => setTimeout(() => resolve({ id: 1, name: "John" }), 1000));
console.log(data);
} catch (error) {
console.error("Ошибка:", error);
}
}
fetchData();
async/await
async/await — это современный синтаксис для работы с асинхронными операциями в JavaScript. Они предоставляют более читаемый способ работы с промисами, делая код линейным и простым.
Ключевые моменты:
async: делает функцию асинхронной, заставляя её возвращать промис.await: используется внутриasync-функций для ожидания выполнения промиса.
async function fetchData() {
return "Данные успешно загружены";
}
fetchData().then(data => console.log(data)); // Вывод: "Данные успешно загружены"
Использование await для работы с промисами:
function getData() {
return new Promise(resolve => {
setTimeout(() => resolve("Данные получены!"), 1000);
});
}
async function process() {
console.log("Ожидание данных...");
const data = await getData(); // Ждём завершения промиса
console.log(data); // Вывод: "Данные получены!"
}
process();
await«останавливает» выполнение функции, пока промис не завершится.- Код выглядит синхронным, хотя выполняется асинхронно.
Обработка ошибок с try/catch:
function fetchData(shouldFail) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject("Ошибка загрузки данных");
} else {
resolve("Данные успешно загружены");
}
}, 1000);
});
}
async function process() {
try {
const data = await fetchData(false); // Попробуйте true для ошибки
console.log(data);
} catch (error) {
console.error("Ошибка:", error); // Обработка ошибки
}
}
process();
Последовательное выполнение:
function step1() {
return new Promise(resolve => setTimeout(() => resolve("Шаг 1 выполнен"), 1000));
}
function step2() {
return new Promise(resolve => setTimeout(() => resolve("Шаг 2 выполнен"), 1000));
}
async function runSteps() {
const result1 = await step1();
console.log(result1);
const result2 = await step2();
console.log(result2);
}
runSteps();
// Вывод:
// Шаг 1 выполнен
// Шаг 2 выполнен
Преимущества async/await:
- Читаемость кода.
- Удобная обработка ошибок через
try/catch. - Легко заменяет цепочки
.thenи.catch.
Ограничения:
- Работает только внутри
async-функций. - Ожидание с
awaitзамедляет выполнение, если нужно запускать задачи параллельно (лучше использоватьPromise.all).
async/await упрощает работу с асинхронностью, делая код понятным и линейным.