首页 > 解决方案 > 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 重写该函数,但我想先听取您的任何意见。

标签: javascriptnode.jstypescriptazure-functions

解决方案


最后,我用javascript重写了这个函数,它按预期工作。我的猜测是这是由于函数编译为 javascript,从 'await' 到 'yield' 的变化弄乱了函数的流程。


推荐阅读