Azure 表服务检索实体"skipping"函数



我有一个聊天机器人,它正在将信息存储到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} });
}
});

基于@Gaurav Mantri发布的内容,我得出了答案。我需要使用async/await来处理botframework活动,此外,这允许我只包装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();

关键(对大多数资深程序员来说可能是显而易见的(是我必须兑现承诺。否则,它只是在等待我对桌子Svc的召唤,因此我马上回到了我开始的地方。通过这种方式设置它,对retrieveEntity的调用将等待解析resolve(notifyEmail),然后使用该值,我的函数的其余部分将根据需要工作。

考虑到tableSvc.retrieveEntity是一个异步操作(因为它进行网络调用并等待响应(,最好等待它的结果。我同意你的看法,等待预定的间隔(在你的情况下是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} });
}
});
});

最新更新