javascript - Azure 函数打字稿未正确等待方法调用
问题描述
我正在开发一个 azure 函数,它接收更新 azure cosmos 数据库的请求。因此,在收到请求后,该函数从数据库中读取项目,如果项目存在,则相应地更新。但它没有按我的预期工作,在函数运行时读取日志,似乎函数不会等到从数据库读取完成。这是代码片段:
const SaasWebhook: AzureFunction = function (context: Context, req: HttpRequest): Promise<void> {
return new Promise(async (resolve, reject) => {
// Initiate azure cosmos db
// Get the payload information
const subscriptionId: string = req.body?.subscriptionId;
const action: string = req.body?.action;
const planId: string = req.body?.planId;
const quantity: string = req.body?.quantity;
let patchedItem: any;
context.log(req.body);
try {
// Read subscription info from the storage
const item: Item = container.item(subscriptionId, subscriptionId);
const { resource: readItem } = await item.read();
context.log("Item from read: ");
context.log(readItem);
// Check the result, data stored in the container is formatted as
if (readItem.id) {
// UPDATE ITEM here
try {
// Try to write the update to the database
const { resource: updatedItem } = await container
.item(id, id)
.replace(patchedItem);
// Give success response
context.log("Operation success. Updated Item: ");
context.log(updatedItem);
context.res = {
status: 200, /* Return error status */
body: "Operation success."
};
resolve();
} catch (error) {
context.res = {
status: 500, /* Return error status */
body: "Operation failure: Item replace failed."
};
reject(error);
}
}
} catch (error) {
context.log("Internal error: failure on accessing Database");
context.log(error);
context.res = {
status: 500, /* Return error status */
body: "Internal error: failure on accessing Database"
};
reject(error);
}
});
}
在记录器上,我会打印这些消息:
2021-02-05T08:14:57.938 [Information] {THE ITEM FROM DATABASE}
2021-02-05T08:14:58.118 [Information] Item from read:
2021-02-05T08:14:58.118 [Information] undefined
2021-02-05T08:14:58.118 [Information] Internal error: failure on accessing Database
2021-02-05T08:14:58.118 [Information] TypeError: Cannot read property 'id' of undefinedat Object.<anonymous> (D:\home\site\wwwroot\dist\SaasWebhook\index.js:43:26)at Generator.next (<anonymous>)at fulfilled (D:\home\site\wwwroot\dist\SaasWebhook\index.js:5:58)at processTicksAndRejections (internal/process/task_queues.js:97:5)
2021-02-05T08:14:58.120 [Error] Executed 'Functions.SaasWebhook' (Failed, Id=ec15bf1b-d9d5-4ebc-900f-73cbc0976b41, Duration=188ms)Result: FailureException: TypeError: Cannot read property 'id' of undefinedStack: TypeError: Cannot read property 'id' of undefinedat Object.<anonymous> (D:\home\site\wwwroot\dist\SaasWebhook\index.js:43:26)at Generator.next (<anonymous>)at fulfilled (D:\home\site\wwwroot\dist\SaasWebhook\index.js:5:58)at processTicksAndRejections (internal/process/task_queues.js:97:5)
就上下文而言,此函数用作 Microsoft 市场 SaaS 实现 API 所需的 webhook,因此如果调用失败,则在一段时间内再次调用该函数,{THE ITEM FROM DATABASE} 日志可能来自该函数的先前调用. 该函数是用打字稿编写的,并通过 Visual Studio Code 上的 Azure 函数扩展上传/部署到 azure 函数。我读过 Typescript 函数实际上在部署之前被编译成一个 javascript 函数,我注意到在 Javascript 函数上,'await' 调用被更改为'yield',这有什么关系吗?这是我的意思的js代码的一部分:
try {
// Read subscription info from the storage
const item = container.item(id, id);
const { resource: readItem } = yield item.read();
context.log("Item from read: ");
context.log(readItem);
...
// The rest doesn't have much difference.
...
我也尝试过使用 item.read().then(...) 而不是 await 并得到了相同的结果。我正在考虑用纯 Javascript 重写该函数,但我想先听取您的任何意见。
解决方案
最后,我用javascript重写了这个函数,它按预期工作。我的猜测是这是由于函数编译为 javascript,从 'await' 到 'yield' 的变化弄乱了函数的流程。