Azure Table 服务 retrieveEntity "skipping" 函数
Azure Table Service retrieveEntity "skipping" the function
我有一个将信息存储到 Azure 表的聊天机器人。在一个用例中,我需要检查实体是否存在,如果存在,则将电子邮件地址附加到实体中的字段并更新它。我正在使用 azure-storage 包。当我第一次开始测试时它工作正常,但经过几次迭代后它开始跳过该功能。我一直在使用调试器并见证了它通过函数的 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} });
}
});
考虑到 tableSvc.retrieveEntity
是一个异步操作(因为它进行网络调用并等待响应到来),最好等待它的结果。我同意你的看法,等待预定时间间隔(在你的情况下为 1.5 秒)不是最佳解决方案。
一种可能的解决方案是将检索实体的调用包装在 returns 一个 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} });
}
});
});
根据@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();
关键(对于大多数资深编码员来说可能显而易见)是我必须 return 一个承诺。否则它只是在等待我对 tableSvc 的调用,因此我就回到了开始的地方。以这种方式设置,对 retrieveEntity 的调用等待解析 resolve(notifyEmail)
,然后在该值可用的情况下,我的函数的其余部分按要求工作。
我有一个将信息存储到 Azure 表的聊天机器人。在一个用例中,我需要检查实体是否存在,如果存在,则将电子邮件地址附加到实体中的字段并更新它。我正在使用 azure-storage 包。当我第一次开始测试时它工作正常,但经过几次迭代后它开始跳过该功能。我一直在使用调试器并见证了它通过函数的 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} });
}
});
考虑到 tableSvc.retrieveEntity
是一个异步操作(因为它进行网络调用并等待响应到来),最好等待它的结果。我同意你的看法,等待预定时间间隔(在你的情况下为 1.5 秒)不是最佳解决方案。
一种可能的解决方案是将检索实体的调用包装在 returns 一个 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} });
}
});
});
根据@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();
关键(对于大多数资深编码员来说可能显而易见)是我必须 return 一个承诺。否则它只是在等待我对 tableSvc 的调用,因此我就回到了开始的地方。以这种方式设置,对 retrieveEntity 的调用等待解析 resolve(notifyEmail)
,然后在该值可用的情况下,我的函数的其余部分按要求工作。