Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 01.03.2024, 10:20
Аспирант
Отправить личное сообщение для roland Посмотреть профиль Найти все сообщения от roland
 
Регистрация: 02.11.2023
Сообщений: 30

class ApiWrapper {
  #client
  #connect

  constructor() {
    this.#client = new DummyClient()
    this.#connect = this.#client.connect()
  }

  async doSomething() {
    await this.#connect
    this.#client.doSomething()
  }
}


Сообщение от Aetae Посмотреть сообщение
ksa, На моём собесе ты бы получил маленький минус(не окончательный) за такое решение.:⁠) Никакой элегантности, левые не нужные таймеры...
У ksa решение простое и читаемое, хоть далеко и не оптимальное.

У Вас же, Aetae, решение проигрывает в простоте и читаемости. Конечно, отчасти это вина первоначального кода, но здесь же не соревнование в скорости написания решений. Для оценки "элегантности" в контексте собеседования решение от самого интервьюера должно быть как минимум простым, читаемым и сопровождаемым.
Ответить с цитированием
  #12 (permalink)  
Старый 01.03.2024, 10:32
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,229

roland, во. Я теперь понял чего в супе не хватало...
Я как раз и не понимал как соединение можно сделать через конструктор.
Ответить с цитированием
  #13 (permalink)  
Старый 01.03.2024, 14:11
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

Я бы сделал как-то так, но метод connect обертки у меня явно костыльный, т.к., имхо, хранить состояние соединения должен сам клиент, а не пытаться открыть соединение на каждый вызов метода `connect`:
interface IClient {
    connect(): Promise<void>;

    doSomething(): Promise<void>;
}

declare const DummyClient: new() => IClient;

class ApiWrapper {
    #client!: IClient;

    #connectionPromise: Promise<void> | null = null;
    #connectionState: 'connected' | 'connecting' | 'disconnected' = 'disconnected';

    constructor(client?: IClient) {
        this.#client = client ?? new DummyClient();
    }

    async connect() {
        if (this.#connectionState !== 'disconnected') {
            return this.#connectionPromise;
        }

        this.#connectionState = 'connecting';

        return this.#connectionPromise = this.#client.connect().then(v => {
            this.#connectionState = 'connected';

            return v;
        }).catch(e => {
            this.#connectionState = 'disconnected';

            throw e;
        });
    }

    async doSomething() {
        await this.connect();

        return this.#client.doSomething();
    }
}


ts playground
Ответить с цитированием
  #14 (permalink)  
Старый 02.03.2024, 13:02
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,590

Nexus, +.

ksa, ну вот примерно как Nexus бы сделал, только выкинул бы возврат оригинального connect (и занулял бы connectionPromise по завершению, чтоб не висело в памяти: что бы там оно не возвращало - оно нам не нужно с гарантией 99%). Ну и connectionPromise назвал бы pendingConnection или просто pending. Но это всё фигня. :⁠)

Кстати нашёл пока лучшее применение chat gpt - придумывать названия переменным и функциям. Решил самую сложную задачу в программировании можно сказать.:⁠)

P.S. В тему о промисах - знает кто-нить готовую либу с нормальной поддержкой, которая бы умела бы делать debounce асинхронной функции, но не простой, а чтоб если таймер вышел - он всё равно не позволял повторного запуска пока предыдущий асинхронный вызов не завершится. Т.е. допустим у нас
const debounced = debounce(async (arg) => {
  console.log(arg);
  await delay(1000);
}, 100);
debounced(1);
await delay(300);
debounced(2);
await delay(300);
debounced(3);

// большинство либ - 1, 2, 3
// иногда - 1, но это debounce, а throttle
// надо - 1, 3

Второй вариант который тоже нужен - более стандрантый, но споддрежкой AbortControler'a, чтоб если таймер вышел и снова вызвали когда предыдущий промис ещё идёт - тригеррил AbortControler.abort();:
// надо - 1/aborted, 2/aborted, 3


Сейчас пишу свою версию, но там не всё так просто..:⁠)
__________________
29375, 35

Последний раз редактировалось Aetae, 02.03.2024 в 14:05.
Ответить с цитированием
  #15 (permalink)  
Старый 03.03.2024, 10:50
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,229

Пока мне больше всего нравится вариант от камрада roland.
Ответить с цитированием
  #16 (permalink)  
Старый 03.03.2024, 21:01
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Сообщение от Nexus
this.#client = client ?? new DummyClient();
имхо, плохая идея. Наметившееся соблюдение DIP сразу идет лесом.

а так, согласен. Хотя, возможно, connectionPromise лучше хранить вообще в самом клиенте. Типа, нужно новое подключение - создали новый клиент.
Ответить с цитированием
  #17 (permalink)  
Старый 03.03.2024, 21:06
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Сообщение от Aetae
// большинство либ - 1, 2, 3

// надо - 1, 3
т.е. в этом примере те либы рисуют 1, 2, 3 с интервалами 300 мс, а тебе нужно, чтобы сначала 2 встала на ожидание, потом её по-тихому сменила 3, и в итоге запустилась 3?
Ответить с цитированием
  #18 (permalink)  
Старый 04.03.2024, 16:46
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,795

Сообщение от Alexandroppolus
имхо, плохая идея. Наметившееся соблюдение DIP сразу идет лесом.
Вот тут, откровенно, не понял. Как зависимость класса нарушает принцип инверсии зависимостей?
Или вы про дефолтное значение?

Если второе, то это из-за условий автора:
Сообщение от AlexandrDr
Исправлять можно только код внутри класса ApiWrapper.
Ответить с цитированием
  #19 (permalink)  
Старый 04.03.2024, 17:29
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Nexus,
а, точно. Не заметил этого странного условия про ApiWrapper.

да, я говорил про дефолтное значение.
Ответить с цитированием
  #20 (permalink)  
Старый 04.03.2024, 19:27
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,590

Сообщение от Alexandroppolus Посмотреть сообщение
т.е. в этом примере те либы рисуют 1, 2, 3 с интервалами 300 мс, а тебе нужно, чтобы сначала 2 встала на ожидание, потом её по-тихому сменила 3, и в итоге запустилась 3?
Вроде так.
Я таки нашёл похожее на то что надо:
1й вариант с 1, 3: perfect-debounce.
Из минусов - промисы завершаются не по порядку: при завершении 1 и начале 3: "одновременно" отстреливаются все предыдущее debunced в порядке 2, 3, 1 с возвратом 1. (возврат 3 ждёт следующих обращений)
Поведение своеобразное, на на мои хотелки ложилось хорошо.

2й вариант с 1/aborted, 2/aborted, 3: awesome-debounce-promise
Только он не использует signal, а свой cancel который оставляет первые два в вечном pending. Довольно интересное, хотя и нишевое решение.

Вообще интересное исследование получилось, о том что разные люди хотят от казалось-бы простой штуки debounce.
В итоге всё равно самописку на signal использовал.
__________________
29375, 35

Последний раз редактировалось Aetae, 04.03.2024 в 19:29.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите решить небольшую задачу kseosru Общие вопросы Javascript 1 24.11.2019 17:08
Помогите решить задачу fillika Events/DOM/Window 2 16.05.2019 11:39
Помогите решить задачу. Alex14 Javascript под браузер 2 29.03.2017 12:18
Помогите решить задачу! Vor_tex Общие вопросы Javascript 0 24.06.2016 13:05
Помогите решить задачу vkg Общие вопросы Javascript 1 20.02.2008 11:59