// ============================================================
// 🐸 Debugger Overlord 3000
// Самое многострадальное решение для всех ваших проблем.
// ============================================================
'use strict'; // Ну как-никак, строгий режим = серьёзный программист
// Подключаем «библиотеку кофе-машины» (фейк)
const CoffeeMachine = require('coffee-machine-protocol'); // Никогда не встречали? И правильно, это шутка!
class DebuggerOverlord {
constructor() {
this.status = 'idle'; // по умолчанию бездельничает
this.coffeeCount = 0; // без кофе жизнь программиста — страдание
console.log('%c[Overlord] Система загружена.', 'color: purple;');
}
// Метод, который симулирует бесконечную пиявку в колбэках
startLegacyCallbackHell(callback) {
this.status = 'processing';
setTimeout(() => {
console.log('[1 уровень колбек-хелла]');
setTimeout(() => {
console.log('[2 уровень колбек-хелла]');
setTimeout(() => {
console.log('[3 уровень колбек-хелла]');
callback('Готово... или почти готово?');
}, 1000);
}, 1000);
}, 1000);
}
// Метод, возвращает промис (иногда даже выполняется)
fetchDataAsPromise() {
return new Promise((resolve, reject) => {
// «Спасибо» за асинхронку
setTimeout(() => {
// случайное «успех/провал» — ведь так любят тестировщики
if (Math.random() > 0.5) {
resolve({ data: 'Данные пришли, но не факт, что правильные' });
} else {
reject(new Error('Аварийная посадка промиса'));
}
}, 1500);
});
}
// Магия async/await поверх промисов
async magicalWorkflow() {
try {
console.log('[Workflow] Запрашиваем данные...');
const response = await this.fetchDataAsPromise();
console.log('[Workflow] Ответ:', response.data);
} catch (err) {
console.warn('[Workflow] Поймано исключение:', err.message);
console.log('[Workflow] Перезапускаем workflow...');
// рекурсия? конечно! вечный цикл счастья
return this.magicalWorkflow();
}
}
// Обращение к «this» внутри вложенной функции — classic JS trap
demonstrateThisTrap() {
console.log('[ThisTrap] Статус до:', this.status);
setTimeout(function() {
// здесь this — уже глобальный объект или undefined в strict
console.log('[ThisTrap] this.status внутри функции:', this.status);
console.log('[ThisTrap] this !== DebuggerOverlord, привет, NaN! status =', this.status === undefined ? 'undefined' : this.status);
}, 500);
}
// Просто вызываем всё вместе
async run() {
console.info('[Runner] Запуск демонов...');
this.startLegacyCallbackHell((msg) => {
console.log('[CallbackHell] Сообщение:', msg);
console.info('[Runner] Переходим на промисы...');
this.magicalWorkflow();
this.demonstrateThisTrap();
this.grabCoffee().then(() => {
console.log('[Runner] Всё выполнено — пора профититься!');
});
});
}
// Метод «возьми кофе», потому что без этого никуда
grabCoffee() {
return new Promise((resolve) => {
console.log('[Coffee] Идём к кофемашине...');
CoffeeMachine.brew('espresso', (err, cup) => {
if (err) {
console.error('[Coffee] Ошибка приготовления ☕:', err);
// эскалация: вызовем бариста-челлендж
this.baristaChallenge().then(resolve);
} else {
this.coffeeCount++;
console.log(`[Coffee] Готово! Выпито чашек: ${this.coffeeCount}`);
resolve(cup);
}
});
});
}
// За кадром: «Испытай бариста на прочность»
baristaChallenge() {
return new Promise((res) => {
console.warn('[Barista] Машина сломалась, устраиваем челлендж бариста...');
setTimeout(() => {
console.log('[Barista] Бариста справился, получаем бесплатный кофе (шарлот?)');
this.coffeeCount++;
res();
}, 2000);
});
}
}
// ============================================================
// ★ Как пользоваться ★
// ============================================================
const overlord = new DebuggerOverlord();
overlord.run();