...

.then() и .catch() в search

Тема в разделе "Примеры сценариев", создана пользователем bashorin, 5 фев 2022.

  1. bashorin

    bashorin Участник

    Часто встречается кейс, когда нужен фильтр в search по дополнительным полям элемента приложения. Например, нам нужно отфильтровать приложение "Компании" по полю "Менеджер", id которого равен текущему пользователю:

    Код:
    
    const currentUser await System.users.getCurrentUser();
    const 
    currUserID currentUser.id;
    const 
    companies await Context.fields.companies.app.search()
        .
    where((fg) => g.and(
            
    f.__deletedAt.eq(null),
        ))
        .
    size(1000)
        .
    all()
        .
    then(=> e.filter(=> e.data.manager!.id == currUserID))

    В итоге мы уже в search отфильтровали по более сложному фильтру наше приложение и получили нужные элементы.

    Так как во then можно прописывать функции, то можно сразу же выполнять какие-то операции с полями нашего приложения:

    Код:
    
    let promisesPromise<void>[] = [];
        
    await Namespace.app.promises.search()
            .
    where((fg) => g.and(
                
    f.__deletedAt.eq(null),
            ))
            .
    size(100)
            .
    all()
            .
    then((e) => {
                
    e.forEach(async (e) => {
                    if (
    e.data.numb == undefined) {
                        
    await e.delete()
                    } else {
                        
    e.data.numb! *= 2;
                    }
                    
    promises.push(e.save())
                })
            })
        if (
    promises.length 0) {
            
    await Promise.all(promises)
        }

    В примере выше, во then мы удаляем элементы приложения, у которых поле numb не заполнено, а у остальных умножаем это поле на 2.

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


    Кроме .then() после .all() нам доступен метод .catch(), в котором мы можем отслеживать ошибки и выполнять что-то, если во .then() что-то пошло не так. В примере ниже мы ищем элементы приложений, у которых поле numb равно 100000, и записываем в контекстную переменную значение numb * 3. Если numb с таким значением нет, то мы переходим в .catch(), где мы можем записать ошибку и найти альтернативное значение numb и записать в Context.data.counter результат с этим значением numb.


    Код:
    
    await Namespace.app.promises.search()
            .
    where((fg) => g.and(
                
    f.__deletedAt.eq(null),
            ))
            .
    size(100)
            .
    all()
            .
    then((e) => {
                const 
    find e.filter(=> i.data.numb! == 100000)
                
    Context.data.counter find[0].data.numb! * 3
            
    })
            .catch(
    async (e) => {
                
    Context.data.error e.message;
                const 
    app await Namespace.app.promises.search()
                    .
    where((fg) => g.and(
                        
    f.__deletedAt.eq(null),
                    ))
                    .
    size(80)
                    .
    all()
                const 
    find app.filter(=> i.data.numb! == 14544)
                
    Context.data.counter find[0].data.numb! * 3
            
    })

    Заключение

    Благодаря использованию .then() и .catch() мы получаем более широкие возможности метода .search(), а также отслеживать ошибки при поиске элементов приложений. При грамотно составленных .then() и .catch(), думаю, можно добиться более предсказуемого, вариативного и поддерживаемого кода: меньше боли при поддержке тем кто написал и тем, кто будет дорабатывать и т.д.

    К сожалению, реальных нагруженных кейсов у меня еще нет, только небольшие запросы, т.к. пришел к этой теме недавно. Если у кого-то что-то есть, примеры, то было очень круто увидеть, или понять, что использование этих методов не нужно или даже бесполезно.
    Последнее редактирование: 9 фев 2022