HowProgrammingWorks - JavaScript and Node.js Programming
Open in Telegram
Программная инжененрия для JavaScript, TypeScrip, Node.js 👉 Group: https://t.me/How_Programming_Works 👉 Node.js channel: https://t.me/metarhia 👉 Node.js group: https://t.me/nodeua
Show more6 575
Subscribers
-724 hours
-47 days
+5930 days
Posts Archive
❓ В четверг 20 марта в 19:00 будет созвон сообщества Метархия, с выпускниками предыдущих наборов по паттернам, ноде и асинхронному программированию. Мы будем стримить его. Можно задать вопросы заранее и мы на них ответим. https://forms.gle/dDZTfR4P6AJFyHfB7
У кого не выходит выбрать язык на лендинге курса, можете сделать это в консоли, при помощи паттернов, самое базовое решение тут, но вы не останавливайтесь:
class Maybe {
constructor(value) {
this.value = value;
}
static of(value) {
return new Maybe(value);
}
map(fn) {
return this.value ? Maybe.of(fn(this.value)) : this;
}
getValue(defaultValue) {
return this.value || defaultValue;
}
}
class SelectCommand {
constructor(selector, value) {
this.selector = selector;
this.value = value;
}
execute() {
return Maybe.of(document.querySelector(this.selector))
.map(el => (el.value = this.value, el))
.map(el => el.dispatchEvent(new Event('change', { bubbles: true })))
.getValue(null);
}
}
const lang = 'RU'; // or UKR
new SelectCommand('.form-select-arrow', lang).execute();🧩 Практический мастер-класс Паттерны в JavaScript и TypeScript
⏰ Начало: в эту субботу 2025-03-22 в 15:00 (Киевское время)
👳 Тимур Шемсединов
🥷 Илья Климов
🧔♂️ Дмитрий Нечай
Изучение Патернов помогает:
✅ Писать более понятный код, который просто читать
✅ Эффективно оптимизировать JavaScript и TypeScript
✅ Быстрее и качественнее решать задачи
✅ Проектировать системы, которые просто изменять
🤖 Регистрация через Телеграмм-бот: https://patterns-js.com/0jiuic?traffic_mark=krzdaj
Скоро в метархии будет новый Emitter оптимизированый для V8, на него переедут протокод metacom, сервер приложений impress, и т.д. но вообще его полезно даже просто почитать: https://github.com/metarhia/metautil/blob/ee/lib/events.js
const ee = new Emitter();
ee.on('eventA', (data) => {
console.log({ data });
// Prints: { data: 'value' }
});
ee.emit('eventA', 'value');
const ee = new Emitter();
setTimeout(() => {
ee.emit('eventA', 'value');
}, 100);
const result = await ee.toPromise('eventA');
const ee = new Emitter();
passReferenceSomewhere(ee);
const iterable = ee.toAsyncIterable('eventB');
for await (const eventData of iterable) {
console.log({ eventData });
}
listenerCount(eventName) {
if (eventName) {
return this.#events.get(eventName)?.length || 0;
}
const listeners = this.#events.values();
return Array.from(listeners).reduce((acc, { length }) => acc + length, 0);
}
eventNames() {
return Array.from(this.#events.keys());
}
}Скоро в Метархии будет оптимизированый для V8 новый Emitter, на который переедут стримы, протокод metacom, все другие части технологии, но его полезно даже просто пичитать: https://github.com/metarhia/metautil/blob/ee/lib/events.js
const DONE = { done: true, value: undefined };
class EventIterator {
#resolvers = [];
#emitter = null;
#eventName = '';
#listener = null;
#onerror = null;
#done = false;
constructor(emitter, eventName) {
this.#emitter = emitter;
this.#eventName = eventName;
this.#listener = (value) => {
for (const resolver of this.#resolvers) {
resolver.resolve({ done: this.#done, value });
}
};
emitter.on(eventName, this.#listener);
this.#onerror = (error) => {
for (const resolver of this.#resolvers) {
resolver.reject(error);
}
this.#finalize();
};
emitter.on('error', this.#onerror);
}
next() {
return new Promise((resolve, reject) => {
if (this.#done) return void resolve(DONE);
this.#resolvers.push({ resolve, reject });
});
}
#finalize() {
if (this.#done) return;
this.#done = true;
this.#emitter.off(this.#eventName, this.#listener);
this.#emitter.off('error', this.#onerror);
for (const resolver of this.#resolvers) {
resolver.resolve(DONE);
}
this.#resolvers.length = 0;
}
async return() {
this.#finalize();
return DONE;
}
async throw() {
this.#finalize();
return DONE;
}
}
class EventIterable {
#emitter = null;
#eventName = '';
constructor(emitter, eventName) {
this.#emitter = emitter;
this.#eventName = eventName;
}
[Symbol.asyncIterator]() {
return new EventIterator(this.#emitter, this.#eventName);
}
}
class Emitter {
#events = new Map();
#wrappers = new Map();
#maxListeners = 10;
constructor(options = {}) {
this.#maxListeners = options.maxListeners ?? 10;
}
emit(eventName, value) {
const listeners = this.#events.get(eventName);
if (!listeners) return Promise.resolve();
const promises = listeners.map((fn) => fn(value));
return Promise.all(promises).then(() => undefined);
}
on(eventName, listener) {
const listeners = this.#events.get(eventName) || [];
if (listeners.includes(listener)) {
throw new Error('Duplicate listeners detected');
}
listeners.push(listener);
this.#events.set(eventName, listeners);
if (listeners.length > this.#maxListeners) {
throw new Error(
`MaxListenersExceededWarning: Possible memory leak. ` +
`Current maxListeners is ${this.#maxListeners}.`,
);
}
}
once(eventName, listener) {
const wrapper = (value) => {
this.off(eventName, listener);
listener(value);
};
wrapper.origin = listener;
this.on(eventName, wrapper);
this.#wrappers.set(listener, wrapper);
}
off(eventName, listener) {
if (!listener) return void this.clear(eventName);
const listeners = this.#events.get(eventName);
if (!listeners) return;
const keep = (f) => f !== listener && f !== this.#wrappers.get(listener);
const updated = listeners.filter(keep);
this.#events.set(eventName, updated);
this.#wrappers.delete(listener);
}
toPromise(eventName) {
return new Promise((resolve) => {
this.once(eventName, resolve);
});
}
toAsyncIterable(eventName) {
return new EventIterable(this, eventName);
}
clear(eventName) {
if (!eventName) {
this.#events.clear();
this.#wrappers.clear();
return;
}
const listeners = this.#events.get(eventName);
if (!listeners) return;
for (const listener of listeners) {
this.#wrappers.delete(listener);
}
this.#events.delete(eventName);
}
listeners(eventName) {
if (eventName) {
const listeners = this.#events.get(eventName) || [];
return listeners.map((listener) => listener.origin || listener);
}
return Array.from(this.#events.values()).flat();
}На что вы всегда найдете время?
Когда внук начал программировать на TypeScript, дедушка переписал на суслика свою квартиру
Repost from Node.js Ukraine Community
В чем преимущество этого фреймворка?
- нет ничего лишнего
- все очень просто
- мы решили все проблемы
- добавлены удобные фишки
- исправлены почти все баги
- заехала новая архитектура папочек
- поддержка TS через удаление типов
- чтобы писать ни нужно знать ничего, ведь это будущее...
💡 Simple optimization examples:
Sources: https://github.com/HowProgrammingWorks/Monomorphism
💡 Как сделать новый популярный фреймворк:
1. Взять один случайный паттерн
2. Дать ему неузнаваемое название
3. Сделать презентацию, пообещав всем, что это и есть решение всех проблем
