3

The AWS SDK documentation is not very clear about when/how/if asynchronous service calls can be made synchronous. For example, this page (https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/calling-services-asynchronously.html) says:

All requests made through the SDK are asynchronous.

Then on this page (https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-a-callback-function.html) it says:

This callback function executes when either a successful response or error data returns. If the method call succeeds, the contents of the response are available to the callback function in the data parameter. If the call doesn't succeed, the details about the failure are provided in the error parameter.

What it doesn't say though is how to wait for that callback function to finish.

For example, is this call asyncronous or synchronous?

new AWS.EC2().describeInstances(function(error, data) {
  if (error) {
    console.log(error); // an error occurred
  } else {
    console.log(data); // request succeeded
  }
});

After describeInstances() has returned, can I assume the callback as been called? If not, how can I wait until it does?

Edit:

So I tried writing some async/await code as suggested, but it doesn't work:

var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
var s3 = new AWS.S3({apiVersion: '2006-03-01'});
let data = null;
r = s3.listBuckets({},function(e,d){
    data = d;
})
p=r.promise();
console.log(">>1",p);

async function getVal(prom) {
    ret = await prom;
    return ret;
}
console.log(">>2",getVal(p));

Now the way I see it I am waiting for the result of getVal() which is awaiting the Promise p, yet this is the result:

>>1 Promise { <pending> }
>>2 Promise { <pending> }

The script just exits without any promise finishing by the looks.

Is it ever possible in Node.js to get the return value of an async function/promise? I am scrathing my head over how simple this would be in Python.

aaa90210
  • 11,295
  • 13
  • 51
  • 88
  • You definitely cannot assume the callback was called (otherwise, why would you even need to use a callback?). [Probable duplicate](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – James Jun 17 '19 at 08:45

1 Answers1

3

When the async call is done, the function that's passed as a parameter, will start. That function has two parameters, (error, data).

  • The first parameter is 'error'. If there is an error, this parameter contain the error message. Else it is empty.
  • The second parameter is data. If there isn't a error, this variable contains the data you need.

One way to retrieve the data is for example use a promise.

const getDescribeInstances = new Promise((resolve, reject) => {
  new AWS.EC2().describeInstances(function(error, data) {
    if (error) return reject(error);

    resolve(data);
  });
}

async function functionToDoSomethingWithTheData(){
  try {
    const describeInstances = await getDescribeInstances();
  }
  catch(error) {
    //handle error
  }
}

By wrap the AWS function inside a promise, you can store the result in a variable.

It needs to be placed in a async function (shown in example) and called place await before it to wait till the function in done.

Oscar R
  • 154
  • 7
  • But if function functionToDoSomethingWithTheData is async, won't I have to find a way to wait on that? – aaa90210 Jun 17 '19 at 10:20
  • If you want to wait on functionToDoSomethingWithTheData, you need to call it inside another async function. Note that you need to put await before it. Maybe can this help you understand the [async / await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) functionality – Oscar R Jun 17 '19 at 10:42
  • How do I wait for my async function to complete then? – aaa90210 Jun 17 '19 at 10:47
  • this is wrong. `getDescribeInstances` needs to be a function that returns a promise. see https://flaviocopes.com/node-promisify/ for a good example of promisifying a function to use it with async/await – stuart Nov 12 '20 at 01:52
  • Is this answer still the best approach, since the SDK now has support for promises? https://aws.amazon.com/blogs/developer/support-for-promises-in-the-sdk/ or is it better to use async/await described here? https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/using-async-await.html – Lazor Mar 22 '21 at 03:11
  • Found something... const { Buckets } = await this.getService().listBuckets({}).promise(); – Lazor Mar 22 '21 at 03:52