Перейти к содержанию
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
Логотип бренда
Категории
JspiJ

Jspi

@Jspi
js
Сводка
Сообщения
33
Темы
17
Поделиться
0
Группы
4
Подписчики
3
Подписки
2

Сообщения

Последние Лучшие сообщения Спорные

  • Дерево из плоского массива функция на Javascript
    JspiJ Jspi

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

    function getTree(dataset) {
        const tree = []; // Дерево будет массивом
        const dataById = new Map(); // Используем Map для хранения узлов
    
        // Создаем индексированный Map и инициализируем childs как массивы
        dataset.forEach(node => {
            dataById.set(node.id, { ...node, childs: [] });
        });
    
        // Строим дерево
        dataset.forEach(({ id, parent }) => {
            const node = dataById.get(id);
            if (!parent) {
                // Если узел не имеет родителя, он становится корневым
                tree.push(node);
            } else {
                // Иначе добавляем узел как дочерний к его родителю
                const parentNode = dataById.get(parent);
                if (parentNode) {
                    parentNode.childs.push(node);
                }
            }
        });
    
        return tree;
    }
    

    Объяснение кода

    Функция возвращает массив tree, содержащий корневые узлы. Каждый узел может иметь дочерние элементы в массиве

    Инициализация

    tree: Массив для хранения корневых узлов.
    dataById: Map, где ключ — id узла, значение — сам узел с добавленным свойством childs (пустой массив).

    Создание индекса (dataById)

    Для каждого узла из dataset создается копия с добавлением пустого массива childs.
    Узел сохраняется в dataById по его id.

    Построение дерева

    Для каждого узла проверяется наличие родителя (parent):

    • Если родителя нет, узел добавляется в массив tree.
    • Если родитель есть, узел добавляется в массив childs родительского узла (если родитель существует).

    Пример использования

    const dataset = [
        { id: 1, parent: null, name: "Root" },
        { id: 2, parent: 1, name: "Child 1" },
        { id: 3, parent: 1, name: "Child 2" },
        { id: 4, parent: 2, name: "Grandchild 1" },
        { id: 5, parent: null, name: "Another Root" }
    ];
    
    const tree = getTree(dataset);
    console.log(JSON.stringify(tree, null, 2));
    

    вывод:

    [
      {
        "id": 1,
        "parent": null,
        "name": "Root",
        "childs": [
          {
            "id": 2,
            "parent": 1,
            "name": "Child 1",
            "childs": [
              {
                "id": 4,
                "parent": 2,
                "name": "Grandchild 1",
                "childs": []
              }
            ]
          },
          {
            "id": 3,
            "parent": 1,
            "name": "Child 2",
            "childs": []
          }
        ]
      },
      {
        "id": 5,
        "parent": null,
        "name": "Another Root",
        "childs": []
      }
    ]
    
    JavaScript

  • Failed: No space left on device на сервере с Next.js
    JspiJ Jspi

    Однажды может случиться так, что на вашем сервере какая-либо команда может вернуть ошибку No space left on device, вы ожидаете, что закончилось место, проверяете его, но все порядке, так в чем же причина?

    Если ваша система наполнена невероятным количеством файлов, то можно достичь предела inodes до того, как исчерпать возможности хранения накопителя. (лучше иметь большие файлы, чем слишком много маленьких)

    Для проверси предела Inodex можно воспользоваться командой:

    sudo df -i
    

    и получить подобное:

    Filesystem      Inodes  IUsed   IFree IUse% Mounted on
    udev            495152    353  494799    1% /dev
    tmpfs           501143    519  500624    1% /run
    /dev/vda1      3276800 3276800      0    100% /
    tmpfs           501143      3  501140    1% /dev/shm
    tmpfs           501143      2  501141    1% /run/lock
    tmpfs           100228     21  100207    1% /run/user/0
    tmpfs           100228     20  100208    1% /run/user/1000
    

    это и значит, что у нас что-то создало очень много мелких файлов.

    Next.js и его кеш могут генерировать очень много файлов

    До 15 версии Next.js все запросы fetch() кешируются по умолчанию, и если ничего не настраивать, то их может скопиться очень много в виде файлов в папке .next/cache/fetch-cache/
    В итоге вам достаточно просто почистить папку с кешем.

    rm -rf .next/cache/fetch-cache
    
    NextJs

  • Тяжело ли быть программистом?
    JspiJ Jspi

    Тяжело, не то что тестерам…
    image.png

    Новости

  • DeepSeek — новая китайская нейросеть
    JspiJ Jspi

    Китай уничтожил ChatGPT — главная тема прямо сейчас. Китайский DeepSeek с командой в 200 человек за 3 дня обошёл ChatGPT в App Store.

    За $6 млн китайцы создали то, на что OpenAI потратила $6,6 млрд и 4500 сотрудников. DeepSeek работает быстрее и бесплатно (а для россиян без VPN).
    Второй удар: Alibaba представили новую модель Qwen2.5-1M, которая может бесплатно генерить картинки и видео, обрабатывать огромные (!) объёмы кода, книги и базы данных. Скорость обработки в 7 раз быстрее.
    Дальше — больше. В ответ на $100 млрд Трампа на «суперкомпьютер» Китай выделяет $137 млрд на развитие ИИ.

    Взлёт DeepSeek связывают с падением рынка акций компаний из США и рынка криптовалют.

    Новости

  • Выгорание в ИТ миф или нет?
    JspiJ Jspi

    зато 300к в наносек

    Юмор, Мемы

  • В чем разница между фронтендом и бекендом?
    JspiJ Jspi

    image.png

    Новости

  • JavaScript мемы
    JspiJ Jspi

    @kirilljs эй, че сразу бить то…

    Юмор, Мемы

  • Программисты раньше и сейчас
    JspiJ Jspi

    cd3d21d5-2ab5-4468-a60f-663672ca975d-image.png

    Юмор, Мемы

  • Программисты c GPT и без
    JspiJ Jspi

    1592f232-946b-4cdd-a492-a923d8a5e49c-image.png
    Раньше при ком-то такой фигни не было

    Юмор, Мемы

  • Проблема с дублированием данных при вызове return вместо reply.send - Fastify
    JspiJ Jspi

    Пользователь @kirilljs написал в Проблема с дублированием данных при вызове return вместо reply.send - Fastify:

    const userService = new UserService();

    Лучше не создавать сервис каждый раз в функции, это лишние затраты

    Fastify

  • Проблема с дублированием данных при вызове return вместо reply.send - Fastify
    JspiJ Jspi

    Во первых ты описал createNewUser() как асинхронную функцию, и она у тебя ничего не возвращает, а также ты нигде await не используешь, у тебя тогда и try не будет ничего ловить

    Попробуй вместо userRepository.save(user) написать асинхронную функцию простую (например таймер), и сделай там console.log(), посмотри сколько сообщений выдаст, сделай такой дебаггинг

    Fastify

  • pm2 автоматический restart при перезагрузки сервера
    JspiJ Jspi

    Пользователь @kirilljs написал в pm2 автоматический restart при перезагрузки сервера:

    Далее нам необходимо запустить скрипт startup, который как раз отвечает за автоматический запуск pm2 после перезагрузки сервера:

    Поправка: команда startup просто показывает команду, при исполнении которой сервис pm2 будет загружать автоматически сохраненные процессы

    Бекенд, разработка серверов

  • PageProps Type Errors in Next.js. Type '{ slug: string; }' is missing the following properties from type 'Promise<any>'
    JspiJ Jspi

    После обновления Next js до 15 версии, в динамических маршрутах разработчики некоторые изменения, что приведет к ошибкам при сборке проекта.

    пример:

    Type error: Type 'Props' does not satisfy the constraint 'PageProps'.
      Types of property 'params' are incompatible.
        Type '{ slug: string; }' is missing the following properties from type 'Promise<any>': then, catch, finally, [Symbol.toStringTag]
    

    Разработчики сделали динамические параметры асинхронными, поэтому нужно будет поменять типы, и получать их мы должны, например, через await

    до 15 версии:

    
    // СТАРЫЙ КОД
    type Props = {
      params: {
        slug: string;
      };
    };   
    
    export async function generateMetadata({ params: { slug } }: Props) {
      const { category } = await fetchData(slug);
    
      ...
      }
    }
    
    export default async function Page({ params: { slug } }: Props) {
      const  data = await fetchData(slug);
    
      ...
    }
    

    после 15 версии:

    // НОВЫЙ КОД
    type Props = {
      params: Promise<{
        slug: string;
      }>;
    };  
    
    export async function generateMetadata(props: Props) {
      const { slug } = await props.params;
      const { category } = await fetchData(slug);
      ...
      }
    }
    
    export default async function Page(props: Props) {
      const { slug } = await props.params;
      const  data = await fetchData(slug);
      ...
    }
    

    Источник

    NextJs errors reactjs

  • Оптимизация React js приложений. Использование функции debounde()
    JspiJ Jspi

    @kirilljs

    Пользователь @kirilljs написал в Оптимизация React js приложений. Использование функции debounde():

    И почему onInput, а не onChange

    onInput отлавливает все изменения значения в <input />, даже такие как нажатие клавиш и вставку текста, поэтому он предпочтительнее в данном случае

    React

  • Оптимизация React js приложений. Использование функции debounde()
    JspiJ Jspi

    Пользователь @kirilljs написал в Оптимизация React js приложений. Использование функции debounde():

    Простыми словами, мы колбэчим submitHandler через debounceHandler то как оно должно быть по спецификации JS

    не понял вопроса, напомню, чтчо тут не используется никаких форм, фактически все обработчики привязаны к onInput событию, функция debounce() - самописная

    React

  • Оптимизация React js приложений. Использование функции debounde()
    JspiJ Jspi

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

    Пример кода

    
    // функция иммитации запроса на сервер
    function fakeFetch(val: string) {
      return new Promise<string>(function (resolve) {
        setTimeout(function () {
          resolve(`Сервер получил сообщение: ${val}`);
        }, 1000);
      });
    }
    
    //  самый простой пример компонента
    function App() {
      const [val, setVal] = useState('');
      const [response, setResponse] = useState('');
    
      const inputHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
        setVal(e.target.value);
        setResponse('');
      };
    
      const submitHandler = async () => {
        setVal('');
        setResponse('отправка ...');
        const resp = await fakeFetch(val);
        setResponse(resp);
      };
    
      return (
        <>
          <input type="text" value={val} onInput={inputHandler} />
          <button onClick={submitHandler}>Отправить</button>
          <p>{response}</p>
        </>
      );
    }
    

    Теперь перед нами встала задача заменить поведение: отправлять данные не по кнопке, а автоматически. Однако мы не может просто так повесить функцию в обработчик inputHandler(), мало того что он будет неоправданно часто отправлять запросы на сервер, так еще и будет сбивать значение val. Но если мы добавить функцию debounce(), то она решит эти вопросы.

    Функция debounce()

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

    пример:

    function debounce(func, delay: number) {
      let timeoutId: number;
    
      return (...args) => {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => func(...args), delay);
      };
    }
    

    Как правильно использовать в React компоненте

    function App() {
      const [val, setVal] = useState('');
      const [response, setResponse] = useState('');
    
      const inputHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
        setVal(e.target.value);
        setResponse('');
    
        debounceHandler();
      };
    
      const submitHandler = useCallback(async () => {
        setResponse('отправка ...');
        const resp = await fakeFetch(val);
        setVal('');
        setResponse(resp);
      }, []);
    
      const debounceHandler = useMemo(() => {
        return debounce(submitHandler, 800);
      }, [submitHandler]);
    
      return (
        <>
          <input type="text" value={val} onInput={inputHandler} />
          {/* <button onClick={submitHandler}>Отправить</button> */}
          <p>{response}</p>
        </>
      );
    }
    

    При изменении стейта функциональный компонент вызывает свою функцию каждый раз, и без мемоизации мы бы получали каждый раз новый обработчик debounceHandler() и submitHandler(). Но для того чтобы все работало нам необходимо передать одну функцию в debounce один раз!

    Поэтому мемоизируем submitHandler() через useCallback (линтер обычно потребует указать submitHandler как зависимость debounceHandler) и саму функцию debounceHandler() в useMemo, (т.к debounce() возвращает функцию)

    React

  • Создание пользователя и базы данных, настройка доступов, установка пароля
    JspiJ Jspi

    Сначала необходимо войти в систему как суперпользователь базы данных на сервере postgresql. Опять же, самый простой способ подключиться в качестве пользователя postgres — это перейти на пользователя postgres unix на сервере базы данных с помощью команды su следующим образом:

    $ su postgres
    

    Далее заходим в среду PostgreSQL

    $ psql
    

    В случае успеха вы должны увидеть следующее:

    postgres=#
    

    В командной строке PostgreSQL создайте базу данных, имя пользователя и пароль, а затем предоставьте весь доступ этому новому пользователю. Например:

    CREATE DATABASE {database};
    CREATE USER {user} WITH PASSWORD 'password';
    GRANT ALL ON DATABASE {database} TO {user};
    

    выходим из среды PostgreSQL

    $ \q 
    

    профит!

    PostgreSQL

  • Ошибка: permission denied for schema public (Postgresql 15)
    JspiJ Jspi

    Если вылезла подобная ошибка:

    driverError: error: permission denied for schema public
    

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

    Нам нужно явно предоставить разрешения пользователю.

    1. Сначала заходим в cli Нашей СУБД
    sudo su postgres
    
    psql -d {database}
    
    1. далее назначаем права
    GRANT ALL ON SCHEMA public TO {user};
    
    1. выходим
    \q
    

    {database} - имя базы данных
    {user} - имя пользователя

    PostgreSQL sql errors
  • Войти

  • Нет учётной записи? Зарегистрироваться

  • Войдите или зарегистрируйтесь для поиска.
  • Первое сообщение
    Последнее сообщение
0
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы