使用 request() 和回调时,如何在 Azure Function 中不调用 context.done() 两次?

How to not call context.done() twice in Azure Function when using request() and callback?

我正在编写一个 Azure 函数,它使用 npm 模块请求调用 Google API。处理 body 的回调需要调用 context.done() 否则 context.res 超出范围(如果我在回调中设置它然后等待在我的脚本末尾通过 context.done()).

问题是我不明白如何处理错误和return对客户端的响应使用回调。

欢迎对我的代码提出任何意见。我要改进。

var request = require('request');

module.exports = function (context, req) {

    if (req.body) {
        incoming = req.body

        if (incoming.components && incoming.components.city
            && incoming.components.state
            && incoming.components.country) {

            // locality = city
            // administrative_area = state
            var country = incoming.components.country;
            var administrative_area = incoming.components.state;
            var locality = incoming.components.city;

            request.get({
                url: "https://maps.googleapis.com/maps/api/geocode/json?components=country:US|locality:city|administrative_area:CA&key=..."
            }, function (error, response, body) {
                if (error) {
                    context.log(error);
                }

                if (!error && response.statusCode == 200) {
                    context.log(body)
                }
                context.res = {
                    status: 200,
                    body: "asdf"
                };
                context.done();
            });

            context.log("here");
        } else {
            context.res = {
                status: 400,
                body: 'There was data but not the right kind. Try {"components": {"country": "US","city": "city","state": "CA"}'
            };
        }

    }
    else {
        context.res = {
            status: 400,
            body: 'Nothing was received. Try {"components": {"country": "US","city": "city","state": "CA"}'
        };
    }
    context.done();
};

您不应在函数结束时调用 context.done()。仅在获得结果时调用它(即当您检测到错误或在回调内部时)。对您的函数进行一点重构和简化:

module.exports = function (context, req) {
    if (!req.body) {
        context.res = {
            status: 400,
            body: 'Nothing was received. Try {"country": "US"}'
        };
        context.done();
        return;
    }

    if (!req.body.country) {
        context.res = {
            status: 400,
            body: 'There was data but not the right kind. Try {"country": "US"}'
        };
        context.done();
        return;
    }        

    request.get({
        url: "https://www.google.com?q=" + req.body.country
    }, function (error, response, body) {
        if (error) {
            context.log(error);
            context.res = {
                status: 500,
                body: "Unexpected error"
            };
        } else {
            if (response.statusCode == 200) {
                context.log(body)
            }
            context.res = {
                status: 200,
                body: "asdf"
            };
        }
        context.done();
    });
};