Node.js-AWS-程序在上载到S3存储桶完成之前终止

时间:2019-04-09 20:42:42

标签: node.js amazon-web-services asynchronous amazon-s3 webdriver-io

我编写了一个创建HTML文件的程序。然后,我尝试在程序结束时将文件上传到我的S3存储桶。看来问题在于我的程序在允许该函数完成或从该函数接收回调之前终止。

这是我代码的要旨:

let aws = require('aws-sdk');

aws.config.update({
    //Censored keys for security
    accessKeyId: '*****',
    secretAccessKey: '*****',
    region: 'us-west-2'
});

let s3 = new aws.S3({
    apiVersion: "2006-03-01",
});

function upload(folder, platform, browser, title, data){
    s3.upload({
        Bucket: 'html',
        Key: folder + platform + '/' + browser + '/' + title + '.html',
        Body: data
    },  function (err, data) {
        if (err) {
            console.log("Error: ", err);
        }
        if (data) {
            console.log("Success: ", data.Location);
        }
    });
}

/*
*
* Here is where the program generates HTML files
*
*/

upload(folder, platform, browser, title, data);

如果在代码的HTML生成部分之前调用upload()函数(配置有测试/虚拟数据),则上传成功。测试文件成功上传到S3。但是,在代码末尾调用该函数时,没有收到错误或成功响应。相反,该程序只是终止而文件没有上载到S3。

在继续执行程序之前,有没有办法等待upload()函数的回调?在将文件上传到S3之前如何防止程序终止?谢谢!

编辑:实施Deiv的答案后,我发现程序 still 仍未上传文件。我仍然没有收到任何成功或错误消息。实际上,该程序似乎只是跳过了upload()函数。为了测试这一点,我在调用console.log("test")之后添加了upload()来查看它是否可以执行。果然,日志成功打印。

这里有关于该项目的更多信息:我正在使用WebdriverIO v4创建有关通过/失败的各种测试的HTML报告。我通过多个事件侦听器(例如this.on('test:start')this.on('suite:end')等)收集测试结果。最后一个事件是this.on('end'),当所有测试完成执行时调用。这里是根据运行该操作系统,浏览器等对测试结果进行排序的方法。

我现在注意到即使我将程序放在处理程序的最开始,程序也不会在this.on('end')事件处理程序中执行与S3相关的任何操作,尽管我仍然确信这是因为没有足够的时间执行,因为处理程序可以处理结果并非常快速地创建HTML文件。我有这段代码列出了我的S3中的所有存储桶:

s3.listBuckets(function (err, data) {
    if (err) {
        console.log("Error: ", err);
    } else {
        console.log("Success: ", data.Buckets);
    }
});

即使在this.on('end')开头运行时,也不会返回任何结果。有人有什么想法吗?我真的很为难。

编辑:这是实现Naveen建议的新代码:

this.on('end', async (end) => {

/*
* Program sorts results and creates variable 'data', the contents of the HTML file.
*/

    await s3.upload({
        Bucket: 'html',
        Key: key,
        Body: data
    }, function (err, data) {
        if (err) {
            console.log("Error: ", err);
        }
        if (data) {
            console.log("Success: ", data.Location);
        }
    }).on('httpUploadProgress', event => {
        console.log(`Uploaded ${event.loaded} out of ${event.total}`);
    });
}

逻辑看起来不错,但仍然没有收到成功或错误消息,并且看不到上传进度。 HTML文件未上传到S3。

1 个答案:

答案 0 :(得分:2)

您可以使用Promise等待上传功能完成。它将是这样的:

function upload(folder, platform, browser, title, data) {
    return new Promise((resolve, reject) => {
        s3.upload({
            Bucket: 'html',
            Key: folder + platform + '/' + browser + '/' + title + '.html',
            Body: data
        }, function(err, data) {
            if (err) {
                console.log("Error: ", err);
                return reject(err);
            }
            if (data) {
                console.log("Success: ", data.Location);
                return resolve();   //potentially return resolve(data) if you need the data
            }
        });
    });
}

/*
*
* Here is where the program generates HTML files
*
*/

upload(folder, platform, browser, title, data)
    .then(data => { //if you don't care for the data returned, you can also do .then(() => {
        //handle success, do whatever else you want, such as calling callback to end the function
    })
    .catch(error => {
        //handle error
    }