Javascript 在函数完成执行之前执行回调

Javascript 在函数完成执行之前执行回调,javascript,node.js,amazon-web-services,amazon-s3,Javascript,Node.js,Amazon Web Services,Amazon S3,您好,我有这个问题,每当我执行这段代码时,回调都会在de main函数完成执行之前执行。我相信这与异步函数有关 var leers3 = async function (next) { var executed = []; AWS.config.update({ region: '********', accessKeyId: '*********', secretAccessKey: '*********' });

您好,我有这个问题,每当我执行这段代码时,回调都会在de main函数完成执行之前执行。我相信这与异步函数有关

var leers3 = async function (next) {
    var executed = [];
    AWS.config.update({
        region: '********',
        accessKeyId: '*********',
        secretAccessKey: '*********'
    });

    var s3 = new AWS.S3();

    s3.listObjects({Bucket:'*******'}, function(err, data) {
        if (err) {
            console.log(fechaActual() + " Error: Error ejecutando cruce con S3.")
        }else{
            var files = [];
            data.Contents.forEach(function(obj,index){
                if(obj.Key.startsWith("*****") || obj.Key.startsWith("*****")){
                    files.push(obj.Key);
                }
            })
            files.forEach((file) => {
                var id_cajero = file.split('_')[1];
                var params = {Bucket:'*****', Key: file};
                var sql = "SELECT id_entidad FROM cajero WHERE id_cajero = '" + id_cajero + "';";
                dbConnection.query(sql, async(err,result) => {
                    if(err) console.log(err);
                    else{
                        var fileExecutedData = await leerarchivos3(params, s3, id_cajero, result[0].id_entidad);
                        fileExecutedData.file = file;
                        executed.push(fileExecutedData);
                        //console.log(executed);    
                    }
                })
                next(executed);                 
            })
        }
    })
};

leers3((executed) => {
        console.log(executed);
    });

我建议将您的
s3.listObjects
调用变成承诺

const data = await s3.listObjects({Bucket:'*******'}).promise();
// ... do things with the data that is currently in your callback
我假设
dbConnection.query
也有一个async/await(即Promise)选项


如果必须使用回调,则应从函数中删除
async
forEach
不是为处理/执行承诺和异步代码而设计的
forEach
设计为同步操作。这意味着,对于您迭代的每个
文件,您认为执行正在暂停,实际上,Javascript将继续到下一次迭代。您将无法保证
dbConnection.query
回调的执行时间。如果您使用
Promise.all
,只需对
Array.map
稍作修改,就可以获得更可预测的结果,并利用“并行”功能
Promise.all
提供的功能。下面是受您的示例启发的伪代码

    await Promise.all(
        files.map((file) => {
            const id_cajero = file.split("_")[1];
            const params = { Bucket: "*****", Key: file };
            const sql = `SELECT id_entidad FROM cajero WHERE id_cajero = '${id_cajero}';`;

            return new Promise((resolve, reject) => {
                dbConnection.query(sql, async (err, result) => {
                    if (err) {
                        return reject(err);
                    }

                    const fileExecutedData = await leerarchivos3(
                        params,
                        s3,
                        id_cajero,
                        result[0].id_entidad
                    );

                    fileExecutedData.file = file;

                    executed.push(fileExecutedData);

                    return resolve();
                });
            });
        })
    );

    next(executed);

哪一个是回调函数,哪一个是你的主要函数?我正在执行页面末尾的Functiont leers3,在里面我定义了一个简单的回调函数。非常感谢你,它工作得非常好,我不得不进一步了解承诺。再次感谢你