

The AWS SDK for JavaScript v2 has reached end-of-support. We recommend that you migrate to [AWS SDK for JavaScript v3](https://docs.aws.amazon.com//sdk-for-javascript/v3/developer-guide/). For additional details and information on how to migrate, please refer to this [announcement](https://aws.amazon.com/blogs//developer/announcing-end-of-support-for-aws-sdk-for-javascript-v2/).

# Calling Services Asychronously
<a name="calling-services-asynchronously"></a>

All requests made through the SDK are asynchronous. This is important to keep in mind when writing browser scripts. JavaScript running in a web browser typically has just a single execution thread. After making an asynchronous call to an AWS service, the browser script continues running and in the process can try to execute code that depends on that asynchronous result before it returns.

Making asynchronous calls to an AWS service includes managing those calls so your code doesn't try to use data before the data is available. The topics in this section explain the need to manage asynchronous calls and detail different techniques you can use to manage them.

**Topics**
+ [Managing Asychronous Calls](making-asynchronous-calls.md)
+ [Using an Anonymous Callback Function](using-a-callback-function.md)
+ [Using a Request Object Event Listener](using-a-response-event-handler.md)
+ [Using async/await](using-async-await.md)
+ [Using JavaScript Promises](using-promises.md)

# Managing Asychronous Calls
<a name="making-asynchronous-calls"></a>

For example, the home page of an e-commerce website lets returning customers sign in. Part of the benefit for customers who sign in is that, after signing in, the site then customizes itself to their particular preferences. To make this happen:

1. The customer must log in and be validated with their sign-in credentials.

1. The customer's preferences are requested from a customer database.

1. The database provides the customer's preferences that are used to customize the site before the page loads.

If these tasks execute synchronously, then each must finish before the next can start. The web page would be unable to finish loading until the customer preferences return from the database. However, after the database query is sent to the server, receipt of the customer data can be delayed or even fail due to network bottlenecks, exceptionally high database traffic, or a poor mobile device connection.

To keep the website from freezing under those conditions, call the database asychronously. After the database call executes, sending your asynchronous request, your code continues to execute as expected. If you don't properly manage the response of an asynchronous call, your code can attempt to use information it expects back from the database when that data isn't available yet.

![\[Showing difference between synchronous and asynchronous execution.\]](http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/images/async-vs-sync.png)


# Using an Anonymous Callback Function
<a name="using-a-callback-function"></a>

Each service object method that creates an `AWS.Request` object can accept an anonymous callback function as the last parameter. The signature of this callback function is:

```
function(error, data) {
    // callback handling code
}
```

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.

Typically the code inside the callback function tests for an error, which it processes if one is returned. If an error is not returned, the code then retrieves the data in the response from the `data` parameter. The basic form of the callback function looks like this example.

```
function(error, data) {
    if (error) {
        // error handling code
        console.log(error);
    } else {
        // data handling code
        console.log(data);
    }
}
```

In the previous example, the details of either the error or the returned data are logged to the console. Here is an example that shows a callback function passed as part of calling a method on a service object.

```
new AWS.EC2({apiVersion: '2014-10-01'}).describeInstances(function(error, data) {
  if (error) {
    console.log(error); // an error occurred
  } else {
    console.log(data); // request succeeded
  }
});
```

## Accessing the Request and Response Objects
<a name="access-request-response"></a>

Within the callback function, the JavaScript keyword `this` refers to the underlying `AWS.Response` object for most services. In the following example, the `httpResponse` property of an `AWS.Response` object is used within a callback function to log the raw response data and headers to help with debugging.

```
new AWS.EC2({apiVersion: '2014-10-01'}).describeInstances(function(error, data) {
  if (error) {
    console.log(error); // an error occurred
    // Using this keyword to access AWS.Response object and properties
    console.log("Response data and headers: " + JSON.stringify(this.httpResponse));
  } else {
    console.log(data); // request succeeded
  }
});
```

In addition, because the `AWS.Response` object has a `Request` property that contains the `AWS.Request` that was sent by the original method call, you can also access the details of the request that was made.

# Using a Request Object Event Listener
<a name="using-a-response-event-handler"></a>

If you do not create and pass an anonymous callback function as a parameter when you call a service object method, the method call generates an `AWS.Request` object that must be manually sent using its `send` method.

To process the response, you must create an event listener for the `AWS.Request` object to register a callback function for the method call. The following example shows how to create the `AWS.Request` object for calling a service object method and the event listener for the successful return.

```
// create the AWS.Request object
var request = new AWS.EC2({apiVersion: '2014-10-01'}).describeInstances();

// register a callback event handler
request.on('success', function(response) {
  // log the successful data response
  console.log(response.data); 
});

// send the request
request.send();
```

After the `send` method on the `AWS.Request` object is called, the event handler executes when the service object receives an `AWS.Response` object.

For more information about the `AWS.Request` object, see [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) in the API Reference. For more information about the `AWS.Response` object, see [Using the Response Object](the-response-object.md) or [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html) in the API Reference.

## Chaining Multiple Callbacks
<a name="response-chaining-callbacks"></a>

You can register multiple callbacks on any request object. Multiple callbacks can be registered for different events or the same event. Also, you can chain callbacks as shown in the following example.

```
request.
  on('success', function(response) {
    console.log("Success!");
  }).
  on('error', function(response) {
    console.log("Error!");
  }).
  on('complete', function() {
    console.log("Always!");
  }).
  send();
```

## Request Object Completion Events
<a name="request-object-completion-events"></a>

The `AWS.Request` object raises these completion events based on the response of each service operation method:
+ `success`
+ `error`
+ `complete`

You can register a callback function in response to any of these events. For a complete list of all request object events, see [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) in the API Reference.

### The success Event
<a name="request-success-event"></a>

The `success` event is raised upon a successful response received from the service object. Here is how you register a callback function for this event.

```
request.on('success', function(response) { 
  // event handler code
});
```

The response provides a `data` property that contains the serialized response data from the service. For example, the following call to the `listBuckets` method of the Amazon S3 service object

```
s3.listBuckets.on('success', function(response) {
  console.log(response.data);
}).send();
```

returns the response and then prints the following `data` property contents to the console.

```
{ Owner: { ID: '...', DisplayName: '...' },
  Buckets: 
   [ { Name: 'someBucketName', CreationDate: someCreationDate },
     { Name: 'otherBucketName', CreationDate: otherCreationDate } ],
  RequestId: '...' }
```

### The error Event
<a name="request-error-event"></a>

The `error` event is raised upon an error response received from the service object. Here is how you register a callback function for this event.

```
request.on('error', function(error, response) { 
  // event handling code
});
```

When the `error` event is raised, the value of the response's `data` property is `null` and the `error` property contains the error data. The associated `error` object is passed as the first parameter to the registered callback function. For example, the following code:

```
s3.config.credentials.accessKeyId = 'invalid';
s3.listBuckets().on('error', function(error, response) {
  console.log(error);
}).send();
```

returns the error and then prints the following error data to the console.

```
{ code: 'Forbidden', message: null }
```

### The complete Event
<a name="request-complete-event"></a>

The `complete` event is raised when a service object call has finished, regardless of whether the call results in success or error. Here is how you register a callback function for this event.

```
request.on('complete', function(response) { 
  // event handler code
});
```

Use the `complete` event callback to handle any request cleanup that must execute regardless of success or error. If you use response data inside a callback for the `complete` event, first check the `response.data` or `response.error` properties before attempting to access either one, as shown in the following example.

```
request.on('complete', function(response) {
  if (response.error) {
    // an error occurred, handle it
  } else {
    // we can use response.data here
  }
}).send();
```

## Request Object HTTP Events
<a name="request-object-http-events"></a>

The `AWS.Request` object raises these HTTP events based on the response of each service operation method:
+ `httpHeaders`
+ `httpData`
+ `httpUploadProgress`
+ `httpDownloadProgress`
+ `httpError`
+ `httpDone`

You can register a callback function in response to any of these events. For a complete list of all request object events, see [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) in the API Reference.

### The httpHeaders Event
<a name="request-httpheaders-event"></a>

The `httpHeaders` event is raised when headers are sent by the remote server. Here is how you register a callback function for this event.

```
request.on('httpHeaders', function(statusCode, headers, response) {
  // event handling code
});
```

The `statusCode` parameter to the callback function is the HTTP status code. The `headers` parameter contains the response headers.

### The httpData Event
<a name="request-httpdata-event"></a>

The `httpData` event is raised to stream response data packets from the service. Here is how you register a callback function for this event.

```
request.on('httpData', function(chunk, response) {
  // event handling code
});
```

This event is typically used to receive large responses in chunks when loading the entire response into memory is not practical. This event has an additional `chunk` parameter that contains a portion of the actual data from the server.

If you register a callback for the `httpData` event, the `data` property of the response contains the entire serialized output for the request. You must remove the default `httpData` listener if you don't have the extra parsing and memory overhead for the built-in handlers.

### The httpUploadProgress and httpDownloadProgress Events
<a name="request-httpupload-download-progress-event"></a>

The `httpUploadProgress` event is raised when the HTTP request has uploaded more data. Similarly, the `httpDownloadProgress` event is raised when the HTTP request has downloaded more data. Here is how you register a callback function for these events.

```
request.on('httpUploadProgress', function(progress, response) {
  // event handling code
})
.on('httpDownloadProgress', function(progress, response) {
  // event handling code
});
```

The `progress` parameter to the callback function contains an object with the loaded and total bytes of the request.

### The httpError Event
<a name="request-httperror-event"></a>

The `httpError` event is raised when the HTTP request fails. Here is how you register a callback function for this event.

```
request.on('httpError', function(error, response) {
  // event handling code
});
```

The `error` parameter to the callback function contains the error that was thrown.

### The httpDone Event
<a name="request-httpdone-event"></a>

The `httpDone` event is raised when the server finishes sending data. Here is how you register a callback function for this event.

```
request.on('httpDone', function(response) {
  // event handling code
});
```

# Using async/await
<a name="using-async-await"></a>

You can use the `async/await` pattern in your calls to the AWS SDK for JavaScript. Most functions that take a callback do not return a promise. Since you only use `await` functions that return a promise, to use the `async/await` pattern you need to chain the `.promise()` method to the end of your call, and remove the callback.

The following example uses async/await to list all of your Amazon DynamoDB tables in `us-west-2`.

```
var AWS = require("aws-sdk");
//Create an Amazon DynamoDB client service object.
dbClient = new AWS.DynamoDB({ region: "us-west-2" });
// Call DynamoDB to list existing tables
const run = async () => {
  try {
    const results = await dbClient.listTables({}).promise();
    console.log(results.TableNames.join("\n"));
  } catch (err) {
    console.error(err);
  }
};
run();
```

**Note**  
 Not all browsers support async/await. See [Async functions](https://caniuse.com/#feat=async-functions) for a list of browsers with async/await support. 

# Using JavaScript Promises
<a name="using-promises"></a>

The `AWS.Request.promise` method provides a way to call a service operation and manage asynchronous flow instead of using callbacks. In Node.js and browser scripts, an `AWS.Request` object is returned when a service operation is called without a callback function. You can call the request's `send` method to make the service call.

However, `AWS.Request.promise` immediately starts the service call and returns a promise that is either fulfilled with the response `data` property or rejected with the response `error` property.

```
var request = new AWS.EC2({apiVersion: '2014-10-01'}).describeInstances();

// create the promise object
var promise = request.promise();

// handle promise's fulfilled/rejected states
promise.then(
  function(data) {
    /* process the data */
  },
  function(error) {
    /* handle the error */
  }
);
```

The next example returns a promise that's fulfilled with a `data` object, or rejected with an `error` object. Using promises, a single callback isn't responsible for detecting errors. Instead, the correct callback is called based on the success or failure of a request.

```
var s3 = new AWS.S3({apiVersion: '2006-03-01', region: 'us-west-2'});
var params = {
  Bucket: 'bucket',
  Key: 'example2.txt',
  Body: 'Uploaded text using the promise-based method!'
};
var putObjectPromise = s3.putObject(params).promise();
putObjectPromise.then(function(data) {
  console.log('Success');
}).catch(function(err) {
  console.log(err);
});
```

## Coordinating Multiple Promises
<a name="multiple-promises"></a>

In some situations, your code must make multiple asynchronous calls that require action only when they have all returned successfully. If you manage those individual asynchronous method calls with promises, you can create an additional promise that uses the `all` method. This method fulfills this umbrella promise if and when the array of promises that you pass into the method are fulfilled. The callback function is passed an array of the values of the promises passed to the `all` method.

In the following example, an AWS Lambda function must make three asynchronous calls to Amazon DynamoDB but can only complete after the promises for each call are fulfilled.

```
Promise.all([firstPromise, secondPromise, thirdPromise]).then(function(values) {
  
  console.log("Value 0 is " + values[0].toString);
  console.log("Value 1 is " + values[1].toString);
  console.log("Value 2 is " + values[2].toString);

  // return the result to the caller of the Lambda function
  callback(null, values);
});
```

## Browser and Node.js Support for Promises
<a name="browser-node-promise-support"></a>

Support for native JavaScript promises (ECMAScript 2015) depends on the JavaScript engine and version in which your code executes. To help determine the support for JavaScript promises in each environment where your code needs to run, see the [ECMAScript Compatability Table](https://compat-table.github.io/compat-table/es6/) on GitHub.

## Using Other Promise Implementations
<a name="using-other-promise-implementations"></a>

In addition to the native promise implementation in ECMAScript 2015, you can also use third-party promise libraries, including:
+ [bluebird](http://bluebirdjs.com)
+ [RSVP](https://github.com/tildeio/rsvp.js/)
+ [Q](https://github.com/kriskowal/q)

These optional promise libraries can be useful if you need your code to run in environments that don't support the native promise implementation in ECMAScript 5 and ECMAScript 2015.

To use a third-party promise library, set a promises dependency on the SDK by calling the `setPromisesDependency` method of the global configuration object. In browser scripts, make sure to load the third-party promise library before loading the SDK. In the following example, the SDK is configured to use the implementation in the bluebird promise library.

```
AWS.config.setPromisesDependency(require('bluebird'));
```

To return to using the native promise implementation of the JavaScript engine, call `setPromisesDependency` again, passing a `null` instead of a library name.