首页 > 解决方案 > Lambda函数:尽管在函数内部将对象推送到它,但数组返回空

问题描述

我将以下代码用作在 API 调用上执行的 lambda 函数。

我遇到的问题是当responsecallback处于当前位置时,即使扫描对象已填充并推送到数组,数组也会scans返回。[]但是,当responsecallback放置在***PLACEHOLDER***部分中时,数组返回填充了扫描对象。

我知道这与代码的异步性质有关,因为我在堆栈上查看了许多类似的问题,但除了 AWS-SDK 代码之外,我不知道该怎么做才能纠正它。

const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient();
const iot = new AWS.Iot;

exports.handler = (event, context, callback) => {   
    iot.listThings(null, function(err, data) {    
        var scans = [];    
        if (err) {
            callback(err, null);
        }
        else {   
            for (var i = 0; i < data.things.length; i++) {
                var device = data.things[i].attributes;
                const params = {
                  // redacted 
                };    
                ddb.query(params, function(err, data) {
                    if (err) {
                        callback(err, null);
                    }
                    else {
                        var scan = {
                            "area": device.area,
                            "count": data["Count"]
                        };
                        scans.push(scan);
                        // ***PLACEHOLDER***
                    }
                });
            }
        }
        var response = {
            "statusCode": 200,
            "headers": {},
            "body": JSON.stringify(scans),
            "isBase64Encoded": false
        };
        callback(null, response);
    });
};

标签: javascriptasynchronousaws-lambdaaws-sdk

解决方案


这是一个异步问题,而不是 Lambda。您的代码应如下所示:

const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient();
const iot = new AWS.Iot;

exports.handler = (event, context, callback) => {   
    iot.listThings(null, function(err, data) {    
        var scans = [];    
        if (err) {
            callback(err, null);
        }
        else {   
            populateScans(data).then(res => {

                callback(null,{
                    "statusCode": 200,
                    "headers": {},
                    "body": JSON.stringify(res),
                    "isBase64Encoded": false
                })
            }).catch(callback)
        }
    });
};

function populateScans(data) {
    return Promise.all(data.things.map(thing => {
        let device = thing.attributes
        const params = {}
        return ddb.query(params).promise().then(res => {
            return {
                area: device.area,
                count: res["Count"]
            }

        })
    }))
}

推荐阅读