首页 > 解决方案 > 在 Node.js 中,在调试中填充了数组,但在正常模式下没有填充

问题描述

在下面的代码中,当我在调试模式下运行时,在这一行有一个断点:content.push(data.Body.toString());我可以看到数据被插入到content数组中。

但是,当我正常运行代码时,content返回为空。

我怎样才能让它填充阵列以供下游使用?

var params = { Bucket: "thebucket", Prefix: "theprefix/" }
var content = [];
function getS3Data()
{    
var s3 = new aws.S3();
s3.listObjects(params, function (err, data) 
{        
    if (err) throw err; // an error occurred
    else 
    {            
        var i;
        for (i = 0; i < data.Contents.length; i++)              
        {
            var currentValue =  data.Contents[i];
            if(currentValue.Key.endsWith(params.Prefix) == false) 
            {
                var goParams = { Bucket: params.Bucket, Key: currentValue.Key };                   
                s3.getObject(goParams, function(err, data) 
                {                        
                    if (err) throw err; //error                        
                    content.push(data.Body.toString());       
                });
            };
        };            
    }//else
});//listObjects
}//getS3Data

getS3Data();

console.log(content); //prints empty here when run in non-debug.

标签: arraysnode.jsamazon-s3aws-sdkdebug-mode

解决方案


行:
console.log(content)
在行之前执行:
content.push(data.Body.toString());

您作为第二个参数传递的函数s3.listObjects将异步执行。如果要注销,content则需要在回调函数含义内进行:

s3.listObjects(params, function (err, data) {        
    if (err) throw err;
    else {            
        // ...
        console.log(content)
    }
});

更好的方法是实现getS3Datawith ,Promise这样您就可以在确定完成对象列表后运行代码。

function getS3Data() {
    return new Promise((resolve, reject) => {
        if (err) {
            reject(err)
        } else {
            const promises = []
            for (const i = 0; i < data.Contents.length; i++) {
                const currentValue = data.Contents[i];
                if (currentValue.Key.endsWith(params.Prefix) == false) {
                    const goParams = { Bucket: params.Bucket, Key: currentValue.Key };
                    promises.push(new Promise((res, rej) => {
                        s3.getObject(goParams, function (err, data) {
                            if (err) {
                                rej(err); //error
                            } else {
                                res(data.Body.toString());
                            }                        
                        });
                    }));
                }
            }
            Promise.all(promises).then(resolve);
        }
    });
}

getS3Data()
    .then(result => { // this will actually be `content` from your code example
        console.log(result);
    }).catch(error => {
        console.error(error);
    })

推荐阅读