javascript - 如何在 Azure Function 中使用 Azure 存储表?

标签 javascript azure azure-functions

恐怕这可能是我完全误解异步工作原理的一个简单例子。

我正在使用 NPM 模块 azure-storage。我遇到的问题是该函数似乎在执行回调之前完成。更糟糕的是,Azure Functions 有一些魔力,您可以通过设置 context.res 属性来“完成”函数。

他们曾经要求您调用 context.done() 但从 v1 到 v2 发生了一些变化,现在我想情况不再是这样了。但即使是这样,该函数也会在回调执行之前结束。

更糟糕的是我的实体甚至没有被插入,但我不知道为什么。

var azure = require('azure-storage');
var validate = require('validate.js');

var constraints = {
    PartitionKey: {
        presence: true,
        email: true
    },
    description: {
        presence: true
    },
    dueDate: {
        presence: true
    }
};

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (!(req.body && req.body.PartitionKey)
        || !(req.body && req.body.description)
        || !(req.body && req.body.dueDate)) {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }

    var tableSvc = azure.createTableService();
    var input = req.body;

    context.log('PartitionKey: ' + input.PartitionKey);
    context.log('description: ' + input.description);
    context.log('dueDate: ' + input.dueDate);

    context.log(validate({ PartitionKey: input.PartitionKey }, constraints));
    context.log(validate({ description: input.description }, constraints));
    context.log(validate({ dueDate: input.dueDate }, constraints));

    var entGen = azure.TableUtilities.entityGenerator;
    var task = {
        PartitionKey: entGen.String(input.PartitionKey),
        RowKey: entGen.String('1'),
        description: entGen.String(input.description),
        dueDate: entGen.DateTime(input.dueDate)
    };

    tableSvc.insertEntity('events', task, function (error, result, response) {
        if (!error) {
            // Entity inserted
            context.log(result);
            context.res = {
                // status: 200, /* Defaults to 200 */
                body: {
                    result: result,
                    response: response
                }
            };
        }
        else {
            context.log(error);
            context.res = {
                status: 400, /* Defaults to 200 */
                body: error
            };
        }
    });
};

最佳答案

导出异步函数时,您可以配置输出绑定(bind)以获取返回值。如果您只有一个输出绑定(bind),建议您这样做。请参阅doc

要使用 return 分配输出,请将 function.json 中的 name 属性更改为 $return。

{
  "type": "http",
  "direction": "out",
  "name": "$return"
}

在这种情况下,您的函数应类似于以下示例:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    // You can call and await an async method here
    return {
        body: "Hello, world!"
    };
}

这应该有效。

您的异步函数不会等待回调。你必须让它等到回调完成。

var azure = require('azure-storage');
var validate = require('validate.js');

var constraints = {
    PartitionKey: {
        presence: true,
        email: true
    },
    description: {
        presence: true
    },
    dueDate: {
        presence: true
    }
};

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (!(req.body && req.body.PartitionKey)
        || !(req.body && req.body.description)
        || !(req.body && req.body.dueDate)) {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }

    var input = req.body;

    context.log('PartitionKey: ' + input.PartitionKey);
    context.log('description: ' + input.description);
    context.log('dueDate: ' + input.dueDate);

    context.log(validate({ PartitionKey: input.PartitionKey }, constraints));
    context.log(validate({ description: input.description }, constraints));
    context.log(validate({ dueDate: input.dueDate }, constraints));

    var entGen = azure.TableUtilities.entityGenerator;
    var task = {
        PartitionKey: entGen.String(input.PartitionKey),
        RowKey: entGen.String('1'),
        description: entGen.String(input.description),
        dueDate: entGen.DateTime(input.dueDate)
    };

    let res = await tablework(task, context);

    if(res.success) {
        return {
            status: 200,
            body: {
                result: res.result,
                response: res.response
            },
            headers: {
                'Content-Type': 'application/json'
            }
        };
    }
    else{

        return {
            status: 400, /* Defaults to 200 */
            body: res.error,
            headers: {
                'Content-Type': 'application/json'
            }
        };
    }

};

function tablework(task, context){
    return (new Promise((resolve, reject) => {
        var tableSvc = azure.createTableService(); 

        tableSvc.insertEntity('events', task, function (error, result, response) {
            if (!error) {
                // Entity inserted
                context.log(result);
                resolve({
                    success: true,
                    result: result,
                    response: response
                });
            }
            else {
                context.log(error);
                resolve({
                    success: false,
                    error: error
                });
            }
        }); 
    }));
}

关于javascript - 如何在 Azure Function 中使用 Azure 存储表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56747300/

相关文章:

python - 如何将 csv 文件从笔记本文件夹传输到数据存储

Azure 使用 ARM 模板标记资源组

c# - Microsoft.Azure.WebJobs.Host.Tables.TableExtension+TableToIQueryableConverter`1[TElement ]' violates the constraint of type ' TElement'

azure - 现有功能无法升级

java - 通过表单向 servlet 发送大量文本

javascript - 在 slider 中播放多个音频文件

javascript - 使用 eventListener 更改 bool 值

javascript - 如何在javascript中获取多个复选框的值

Azure 应用程序服务 - Docker 组成多容器应用程序 - 无 Docker 日志

azure - Azure Function 中的本地文件