Azure Table Service retrieveEntity «пропускает» функцию - PullRequest
0 голосов
/ 14 марта 2020

У меня есть чат-бот, который хранит информацию в Azure таблицах. В одном случае использования мне нужно проверить и посмотреть, существует ли объект, и если да, добавить адрес электронной почты в поле в объекте и обновить его. Я использую azure -хранилище. Когда я впервые начал тестировать, он работал, но после нескольких итераций он начал пропускать функцию. Я использовал отладчик и был свидетелем его прохождения через часть функции if (!err). Однако, не изменяя (насколько мне известно) какой-либо код, теперь он пропускает всю функцию. Я ставлю дополнительные точки останова в операторах if и else, а также в самом конце функции, но она просто обходит все и переходит прямо к следующему блоку кода. Этот следующий блок заменяет сущность, и на самом деле он работает нормально. Только retrieveEntity не работает. Я не могу придумать, почему это не сработает. Любые идеи? Функционально я не вижу никакой причины, по которой он вообще не попадет в функциональный блок, и еще больше озадачен тем, что он работал в какой-то момент. Вот блок кода для retrieveEntity и insertOrReplaceEntity.

            tableSvc.retrieveEntity('orderData', 'Vista', lineKey, function(err, result, response) {
                if (!err) {
                    if (!result.userEmail._.includes(conversationData.userEmail)) {
                        notifyEmail = `${result.userEmail._}, ${conversationData.userEmail}`;
                    } else {
                        notifyEmail = result.userEmail._;
                    }
                } else {
                    notifyEmail = conversationData.userEmail;
                }
            });

<<some code to define lineData for entity>>

                tableSvc.insertOrReplaceEntity('orderData',lineData, async function (err, result, response) {
                    if (!err) {
                        await step.context.sendActivity('OK, I will let you know once this line item ships.');
                        this.appInsightsClient.trackTrace({message: `Table API - ${path.basename(__filename)}`,severity: 1,properties: {request:lineData, response:response} });
                    } else {
                        console.log(err);
                        await step.context.sendActivity(`I wasn't able to set up that notification for you. Please try your search again later, and if your line still hasn't shipped I can try to set it up again.`);
                        this.appInsightsClient.trackTrace({message: `${err.name}/${err.code} - ${path.basename(__filename)}`,severity: 4,properties: {'request':lineData, 'error':err.message} });
                    }
                });

Ответы [ 2 ]

1 голос
/ 16 марта 2020

Опираясь на то, что написал @Garav Mantri, я смог прийти к ответу. Мне нужно было использовать async / await для обработки действий с бот-фреймами, и, кроме того, это позволило мне только обернуть функцию retrieveEntity, а не обернуть остальную часть кода. Вот как я решил это.

            async function retrieveEntity() {
                return new Promise((resolve) => {
                    tableSvc.retrieveEntity('orderData', 'Vista', lineKey, function(err, result, response) {
                        if (!err) {
                            console.log(result.userEmail._, conversationData.userEmail);
                            if (!result.userEmail._.includes(conversationData.userEmail)) {
                                notifyEmail = `${result.userEmail._},${conversationData.userEmail}`;
                            } else {
                                notifyEmail = result.userEmail._;
                            }
                            resolve(notifyEmail);
                        } else {
                            notifyEmail = conversationData.userEmail;
                            resolve(notifyEmail);
                        }
                    });
                }); 
            }
            await retrieveEntity();

Ключ (вероятно, очевидный для большинства опытных программистов) состоял в том, что я должен был вернуть обещание. В противном случае он просто ожидал моего вызова таблицы SV c и, таким образом, я сразу вернулся к тому, с чего начал. Настраивая его таким образом, вызов retrieveEntity ожидает разрешения resolve(notifyEmail), а затем с этим доступным значением остальная часть моей функции работает как требуется.

1 голос
/ 14 марта 2020

Учитывая, что tableSvc.retrieveEntity является асинхронной c операцией (поскольку она выполняет сетевой вызов и ожидает ответа), лучше дождаться ее результата. Я согласен с вами, что ожидание предопределенного интервала (в вашем случае 1,5 секунды) не является оптимальным решением.

Одним из возможных решений является завершение вызова для извлечения сущности в функцию, которая возвращает Promise, поэтому что вы ждете, пока это обещание будет выполнено.

Вот псевдокод, который я придумал (не проверял):

function retrieveEntity() {
    return new Promise((resolve) => {
        tableSvc.retrieveEntity('orderData', 'Vista', lineKey, function(err, result, response) {
            if (!err) {
                if (!result.userEmail._.includes(conversationData.userEmail)) {
                    notifyEmail = `${result.userEmail._}, ${conversationData.userEmail}`;
                } else {
                    notifyEmail = result.userEmail._;
                }
                resolve(notifyEmail);
            } else {
                notifyEmail = conversationData.userEmail;
                resolve(notifyEmail);
            }
        });
    });
}

retrieveEntity
.then((result) => {
    //some code to define lineData for entity
    //
    //

    tableSvc.insertOrReplaceEntity('orderData',lineData, async function (err, result, response) {
        if (!err) {
            await step.context.sendActivity('OK, I will let you know once this line item ships.');
            this.appInsightsClient.trackTrace({message: `Table API - ${path.basename(__filename)}`,severity: 1,properties: {request:lineData, response:response} });
        } else {
            console.log(err);
            await step.context.sendActivity(`I wasn't able to set up that notification for you. Please try your search again later, and if your line still hasn't shipped I can try to set it up again.`);
            this.appInsightsClient.trackTrace({message: `${err.name}/${err.code} - ${path.basename(__filename)}`,severity: 4,properties: {'request':lineData, 'error':err.message} });
        }
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...