简体   繁体   中英

How to Return variable from AWS getObject call in Node.js

I am working on a Node.js project that relies on the response of getObject from AWS. Currently, I can access the data I need and store it in a variable ( header ), but do not know how to make it available in the main function.

TileStreamerS3.prototype.Init = function(filepath, index, s3config){
   var retval = false; 
   AWS.config.update({accessKeyId: s3config.access_key, secretAccessKey: s3config.secret_key});
   var blc = new BlockLibraryConfigs(); 
   var awsConfig = blc.awsConfig; 
   AWS.config.update({region: awsConfig.region}); 

   var aws = new AWS.S3(); 
   var params = {
       Bucket: s3config.bucket, 
       Key: s3config.tile_directory + filepath, 
       Range: 'bytes=0-27'
   };



 aws.getObject(params, function(err, data){
       if(err == null){
            var header = bufferpack.unpack('<7I', data.Body);
            return header; 
       }
   }); 
}; 

How do I return the header variable? I saw a possible solution that used JQuery, but I'm on Windows and am having issues getting JQuery to work with Node. I don't want to have to go down that path if there's a better way to do it.

UPDATE: I know there are multiple questions regarding returning values from asynchronous functions. I think what's tripping me up is that aws.getObject() is a function that is taking in another function as a parameter. I want to return the header value from the function that is a parameter for the aws.getObject() function. Furthermore, I have no access to change the getObject() function.

The first thing to understand about asynchronous programming is that you cannot actually return the result from your callback to your main function or anywhere else. Here's a tutorial on async coding to get you started .


As for your current situation, I would handle it using Async Waterfall . Async will force the otherwise asynchronous functions to behave synchronously by waiting for them to finish before calling the next function (with the output of the previous function as arguments to the next function).

Here is an example:

TileStreamerS3.prototype.Init = function(filepath, index, s3config, callback) {
// pass a callback function as a parameter

    var retval = false;
    AWS.config.update({
        accessKeyId: s3config.access_key,
        secretAccessKey: s3config.secret_key
    });
    var blc = new BlockLibraryConfigs();
    var awsConfig = blc.awsConfig;
    AWS.config.update({ region: awsConfig.region });

    var aws = new AWS.S3();
    var params = {
        Bucket: s3config.bucket,
        Key: s3config.tile_directory + filepath,
        Range: 'bytes=0-27'
    };

    async.waterfall([function(callback) {

        aws.getObject(params, function(err, data) {
            if (!err) {
                var header = bufferpack.unpack('<7I', data.Body);

                callback(null, header); // using this we are passing the control to the
                // next function in the array
            }
        });

    }, function(header, callback) { // this is the function which will be called 
        // synchronously from aws.getObject's callback

        // use the header value passed from the previous function
        // do the next bit of asynchronous computation

        callback(null, output_if_any); // call the next function or the final callback

    }], callback); // attach the callback function to the async.waterfall

    // due to the async nature of the code, anything written after the waterfall will
    // be executed before the above code! So if you try to set any variable within the 
    // async function's callback and console.log it here, you will get undefined.

};

What happens here is that using async.waterfall we can create a list of functions (each of which may contain asynchronous functions) to be called synchronously one-after-the-other. When all the functions have been executed, the final callback function at the end is called with the output results .

Now when you call the function TileStreamerS3.Init , you do it like this:

TileStreamerS3Object.Init(filepath, index, s3config, function(err, results) {

    if (err) {
        // handle the error
    } else {
        // do whatever you want with the results
        // and continue the processing
    }

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM