Javascript Lambda函数:数组返回空,尽管在函数内部将对象推给它

Javascript Lambda函数:数组返回空,尽管在函数内部将对象推给它,javascript,asynchronous,aws-lambda,aws-sdk,Javascript,Asynchronous,Aws Lambda,Aws Sdk,我使用下面的代码作为对API调用执行的lambda函数 我遇到的问题是,当响应和回调处于其当前位置时,数组扫描返回[],即使已填充扫描对象并将其推送到数组中。但是,当响应和回调放在***占位符***部分时,数组返回填充了扫描对象的结果 我理解这与代码的异步性质有关,因为我已经研究了堆栈上的许多类似问题,但除了AWS-SDK代码之外,我不知道如何纠正它 const AWS = require('aws-sdk'); const ddb = new AWS.DynamoDB.DocumentClie

我使用下面的代码作为对API调用执行的lambda函数

我遇到的问题是,当响应和回调处于其当前位置时,数组扫描返回[],即使已填充扫描对象并将其推送到数组中。但是,当响应和回调放在***占位符***部分时,数组返回填充了扫描对象的结果

我理解这与代码的异步性质有关,因为我已经研究了堆栈上的许多类似问题,但除了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);
    });
};

这是一个异步问题,而不是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"]
            }

        })
    }))
}

可能重复我的投票结果,因为我认为这会有所帮助,但我不确定它是否完全涵盖了当前的问题基本上,扫描是在iot.listThings内部定义的,在iot.listThings外部无法访问。将var scans=[]移到exports.handler上方,或通过上下文参数将其传入,这应该可以解决问题。不,他的问题是扫描是在循环内部定义的,在iot.listThings外部无法访问。将var scans=[]移到exports.handler上方,或通过上下文参数将其传入,这应该可以解决他的问题。@AdamH不同意…扫描会在后续回调中填充,因此需要在此类回调中调用lambda回调。facepalm我现在看到响应的构建-我是个傻瓜。留下我以前的评论,这样你就不会看起来像一个疯子在和谁打架地狱伤害了我的大脑。在Promise land或async/await中,我将通过now@Giles,不确定count=3来自何处。我在数组中看到2个对象