Проблема с обещаниями и тайм-аутом кода при вставке данных в коллекцию - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь проверить, существует ли объект в коллекции wix и отменяет ли он вызов inset () для базы данных

import wixData from "wix-data";

export function Memberships_beforeInsert(item, context) {
    var name = item.firstName + item.lastName;
    name = name.toLowerCase();
    wixData.query(context.collectionName)
    .find()
    .then((res) => {
        var members = res.items;
        var len = res.length;
        console.log(len)
        for (var i = 0; i < len; i++) {
            let member = members[i];
            let memberName = member.firstName + member.lastName;
            memberName = memberName.toLowerCase();

            if (memberName === name) {
            let toUpdate = {
                    '_id': member._id
            }
            wixData.update(context.collectionName, toUpdate)

            return null;
            }
            return item;

        }

    });
    //toHere    
}

Я довольно новичок в и в wixCode, но я ожидал, что это подождет, пока не будет вызван .then (), а затем вернется следующим образом, но из-за использования wixCode обещаний код сразу переходит в раздел кода //toHere в который не находит ответ и отклоняет вызов. Который добавляет данные в базу данных вместо того, чтобы возвращать ноль.

1 Ответ

0 голосов
/ 23 января 2019

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

Так быстро, что такое обещание?

С точки зрения непрофессионала, думайте о Promise как о коде отслеживания FedEx.

Когда вы вызываете функцию, основанную на обещании, чтобы попросить ее сделать что-то, вы получаете обещание, что то, о чем вы просили, будет выполнено или вам сообщат, если возникла проблема.

Точно так же, как с помощью кода отслеживания по федеральному закону - вы не знаете, прибыло ли что-то (ваша функция выполнила то, что вы хотите), если вы не проверите статус отслеживания с помощью кода ИЛИ не прибудет фургон доставки FedEx и вы не получите пакет. В этот момент код отслеживания обновляется, чтобы сообщить, что посылка была доставлена, и вы можете получить текст или электронное письмо о том, что оно было доставлено.

Функция Promise либо успешно завершается, и вы получаете результат при вызове функции then ИЛИ, если происходит ошибка, запускается событие catch (). Таким образом, все функции, основанные на Promise, похожи на условные тесты, только если они выглядят так:

sendFedEx(package) // Call doesn't resolve immediately you have to wait for fedEx!
.then((fedExDeliveryInfo) => {
    //Your package arrived!
})
.catch((fedExLostPackageInfo) => {
    //Your package got lost :-(
});

В вашем коде вы выполняете сравнение без учета регистра за пределами сбора данных. Вероятно, это потребует значительных ресурсов при большом сборе данных. Лучше было бы хранить строку без учета регистра: (item.firstName + item.lastName) .toLowerCase () в записи данных, а затем используйте его для запроса с использованием .eq. Таким образом, вы позволяете сбору данных выполнять свою работу и упрощаете свой код. Примечание. При этом используется тот факт, что beforeInsert () возвращает Promise.

Синтаксис

функция beforeInsert (элемент: Объект, контекст: HookContext): Обещание

Вот измененное предложение для вас с большим количеством комментариев!

import wixData from "wix-data";

export function Memberships_beforeInsert(item, context) {
    // Memberships_beforeInsert returns a promise. So does 
    // wixData.query...find() so we simply return it to maintain the Promise
    // chain.
    var compareName = (item.firstName + item.lastName).toLowerCase();

    // Add a compareName column value to item for future querying
    // This will be inserted into the data collection
    item.compareName = compareName;

    //-------------------------------------------------------//
    // This is the head of the Promise chain we need to return
    //-------------------------------------------------------//
    return wixData.query(context.collectionName)
    .eq('compareName', item.compareName) // Query the compareName
    .find()
    .then((res) => {
        var members = res.items;
        var len = res.length;
        console.log(len);
        // Should only have one record or no records otherwise we have a
        // problem with this code :-)

        // So if we have too many we throw and error. This will be caught in
        // an outer catch if we have one
        if (len > 1) {
            throw Error(`Internal Error! Too many records for ${item.firstName} ${item.lastName}`);
        }

        // If we get here we have a valid record OR we need to return a result
        // To do this we will use a return variable set to the item which 
        // assumes we will insert item. This will be overridden with the save
        // Promise if we have a record already
        var result = item;

        if (len === 1) {
            // We have a record already so we need to update it and return null
            // to the caller of beforeInsert to halt the insert. This is a
            // Simple case of adding the _id of the found record to the item we
            // have been given.
            item['_id'] = member._id;

            // Again remember we are using promises so we need to return the
            // wixData.update result which is a promise.
            result = wixData.update(context.collectionName, toUpdate)
            .then((savedRecord) => {
                // Now we have chained the update to the beforeInsert response
                // This is where we can tell the Insert function to abort by
                // returning null.
                return null;
            });

        }

        // Now we can return the result we have determined to the caller
        return result;

    });    
}

Это должно делать то, что вы пытаетесь достичь.

...