

La versión 2 de AWS SDK para JavaScript ha llegado al final del soporte. Se recomienda que migre a [AWS SDK para JavaScript v3](https://docs.aws.amazon.com//sdk-for-javascript/v3/developer-guide/). Para ver detalles e información adicionales sobre cómo realizar la migración, consulte este [anuncio](https://aws.amazon.com/blogs//developer/announcing-end-of-support-for-aws-sdk-for-javascript-v2/).

# Uso de los servicios en el SDK para JavaScript
<a name="working-with-services"></a>

El AWS SDK para JavaScript proporciona acceso a los servicios que admite a través de una colección de clases del cliente. A partir de estas clases del cliente, se crean objetos de interfaz de servicios, normalmente denominados *objetos de servicio*. Cada servicio de AWS compatible tiene una o varias clases del cliente que ofrecen API de bajo nivel para utilizar características de servicio y recursos. Por ejemplo, las API de Amazon DynamoDB están disponibles a través de la clase `AWS.DynamoDB`.

Los servicios expuestos a través del SDK para JavaScript siguen el patrón de solicitud-respuesta para intercambiar mensajes con las aplicaciones que llaman. En este patrón, el código que invoca un servicio envía una solicitud HTTP/HTTPS a un punto de conexión para el servicio. La solicitud contiene parámetros necesarios para invocar correctamente la característica específica a la que se llama. El servicio que se invoca genera una respuesta que se devuelve al solicitante. La respuesta contiene datos si la operación se ha realizado correctamente o bien contiene información de error si dicha operación ha generado errores. 

![\[El patrón de servicio de solicitud-respuesta de AWS.\]](http://docs.aws.amazon.com/es_es/sdk-for-javascript/v2/developer-guide/images/request-response.png)


La invocación de un servicio de AWS incluye el ciclo de vida completo de solicitud y respuesta de una operación en un objeto de servicio, incluidos todos los reintentos. El objeto `AWS.Request` encapsula una solicitud en el SDK. La respuesta se encapsula en el SDK mediante el objeto `AWS.Response`, que se proporciona al solicitante a través de una de varias técnicas como, por ejemplo, una función de devolución de llamada o una promesa de JavaScript.

**Topics**
+ [Creación y llamada a objetos de servicio](creating-and-calling-service-objects.md)
+ [Registro de llamadas del AWS SDK para JavaScript](logging-sdk-calls.md)
+ [Llamadas asíncronas a servicios](calling-services-asynchronously.md)
+ [Uso del objeto de respuesta](the-response-object.md)
+ [Uso de JSON](working-with-json.md)
+ [Estrategia de reintentos en la versión 2 de AWS SDK para JavaScript](retry-strategy.md)

# Creación y llamada a objetos de servicio
<a name="creating-and-calling-service-objects"></a>

La API de JavaScript admite la mayoría de los servicios de AWS disponibles. Cada clase de servicio de la API de JavaScript proporciona acceso a todas las llamadas a la API de su servicio. Para obtener más información acerca de clases de servicios, las operaciones y los parámetros en la API de JavaScript, consulte la [referencia de la API](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/index.html).

Cuando utiliza el SDK en Node.js, añade el paquete del SDK a su aplicación mediante `require`, que ofrece soporte para todos los servicios actuales.

```
var AWS = require('aws-sdk');
```

Cuando utiliza el SDK con JavaScript de navegador, carga el paquete del SDK en los scripts de navegador mediante el paquete de SDK alojado en AWS. Para cargar el paquete del SDK, añada el siguiente elemento `<script>`.

```
<script src="https://sdk.amazonaws.com/js/aws-sdk-SDK_VERSION_NUMBER.min.js"></script>
```

Para encontrar el SDK\$1VERSION\$1NUMBER actual, consulte la referencia de API para el SDK para JavaScript en la [Guía de referencia de la API de AWS SDK para JavaScript](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/).

El paquete de SDK alojado predeterminado admite un subconjunto de los servicios de AWS disponibles. Para obtener una lista de los servicios predeterminados en el paquete del SDK hospedado para el navegador, consulte los [servicios compatibles](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/#Supported_Services) en la referencia de la API. Puede utilizar el SDK con otros servicios si la comprobación de seguridad CORS está deshabilitada. En este caso, puede crear una versión personalizada del SDK para incluir los servicios adicionales que necesita. Para obtener más información acerca de la creación de una versión personalizada del SDK, consulte [Creación del SDK para navegadores](building-sdk-for-browsers.md).

## Necesidad de uso de servicios individuales
<a name="requiring-individual-services"></a>

Si necesita usar el SDK para JavaScript tal y como se muestra anteriormente, tiene que incluir todo el SDK en el código. O bien, puede elegir exigir solo los servicios individuales que su código utiliza. Considere el siguiente código que se utiliza para crear un objeto de servicio de Amazon S3.

```
// Import the AWS SDK
var AWS = require('aws-sdk');

// Set credentials and Region
// This can also be done directly on the service client
AWS.config.update({region: 'us-west-1', credentials: {YOUR_CREDENTIALS}});

var s3 = new AWS.S3({apiVersion: '2006-03-01'});
```

En el ejemplo anterior, la función `require` especifica todo el SDK. La cantidad de código que debe transportarse a través de la red, así como la sobrecarga de memoria del código serían considerablemente inferiores si solo se incluyese una parte del SDK que necesita para el servicio de Amazon S3. Para solicitar un servicio individual, llame a la función `require` tal y como se muestra, incluido el constructor de servicio todo en minúsculas.

```
require('aws-sdk/clients/SERVICE');
```

A continuación se muestra cómo se ve el código para crear el objeto de servicio de Amazon S3 anterior cuando incluye solo la parte de Amazon S3 del SDK.

```
// Import the Amazon S3 service client
var S3 = require('aws-sdk/clients/s3');
 
// Set credentials and Region
var s3 = new S3({
    apiVersion: '2006-03-01',
    region: 'us-west-1', 
    credentials: {YOUR_CREDENTIALS}
  });
```

Puede seguir obteniendo acceso al espacio de nombres de AWS global sin tener todos los servicios asociados a él.

```
require('aws-sdk/global');
```

Se trata de una técnica útil cuando se aplica la misma configuración en varios servicios individuales para, por ejemplo, proporcionar las mismas credenciales a todos los servicios. La necesidad de servicios individuales debería reducir el tiempo de carga y el consumo de memoria en Node.js. Cuando se realiza con una herramienta de agrupación como Browserify o Webpack, el uso de servicios individuales hace que el SDK se reduzca a una fracción del tamaño completo. Esto es útil en los entornos con memoria o espacio de disco restringidos, como un dispositivo IoT o una función de Lambda.

## Creación de objetos de servicio
<a name="creating-service-objects"></a>

Para obtener acceso a características de servicio a través de la API de JavaScript, primero debe crear un *objeto de servicio* a través del cual obtener acceso a un conjunto de características que proporciona el cliente subyacente. Por lo general cada servicio proporciona una clase de cliente; sin embargo, algunos servicios dividen el acceso a sus características entre varias clases de cliente.

Para utilizar una característica, debe crear una instancia de la clase que proporciona acceso a dicha característica. En el siguiente ejemplo se muestra cómo crear un objeto de servicio para DynamoDB a partir de la clase de cliente `AWS.DynamoDB`.

```
var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
```

De forma predeterminada un objeto de servicio se configura con la configuración global que también se utiliza para configurar el SDK. Sin embargo, puede configurar un objeto de servicio con datos de configuración de tiempo de ejecución específicos de dicho objeto de servicio. Los datos de configuración específicos del servicio se aplican después de aplicar los valores de la configuración global.

En el ejemplo siguiente, se crea un objeto de servicio de Amazon EC2 con la configuración para una región específica, pero aparte de esto se utiliza la configuración global.

```
var ec2 = new AWS.EC2({region: 'us-west-2', apiVersion: '2014-10-01'});
```

Además de admitir la configuración específica del servicio aplicada a un objeto de servicio individual, también puede aplicar la configuración específica del servicio a todos los objetos de servicio recién creados de una determinada clase. Por ejemplo, para configurar todos los objetos de servicio creados a partir de la clase de Amazon EC2 para utilizar la región Oeste de EE. UU. (Oregón) (`us-west-2`), añada lo siguiente al objeto de configuración global `AWS.config`.

```
AWS.config.ec2 = {region: 'us-west-2', apiVersion: '2016-04-01'};
```

## Bloqueo de la versión de API de un objeto de servicio
<a name="locking-api-version-of-service-objects"></a>

Puede bloquear un objeto de servicio en una versión de API específica de un servicio especificando la opción `apiVersion` al crear el objeto. En el siguiente ejemplo, se crea un objeto de servicio de DynamoDB que está bloqueado para una versión de API específica.

```
var dynamodb = new AWS.DynamoDB({apiVersion: '2011-12-05'});
```

Para obtener más información acerca del bloqueo de la versión de la API de un objeto de servicio, consulte [Bloqueo de versiones de la API](locking-api-versions.md).

## Especificación de parámetros de objetos de servicio
<a name="specifying-service-object-parameters"></a>

Al llamar a un método de un objeto de servicio, transfiera los parámetros en JSON según los requiera la API. Por ejemplo, en Amazon S3, para obtener un objeto para un bucket y una clave especificados, transfiera los siguientes parámetros al método `getObject`. Para obtener más información acerca de cómo transferir parámetros JSON, consulte [Uso de JSON](working-with-json.md).

```
s3.getObject({Bucket: 'bucketName', Key: 'keyName'});
```

Para obtener más información acerca de los parámetros de Amazon S3, consulte [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html) en la referencia de la API.

Además, puede vincular valores a parámetros individuales al crear un objeto de servicio mediante el parámetro `params`. El valor del parámetro `params` de objetos de servicio es un mapa que especifica uno o varios valores de parámetros definidos por el objeto de servicio. En el siguiente ejemplo se muestra el parámetro `Bucket` de un objeto de servicio de Amazon S3 vinculado a un bucket llamado `amzn-s3-demo-bucket`.

```
var s3bucket = new AWS.S3({params: {Bucket: 'amzn-s3-demo-bucket'}, apiVersion: '2006-03-01' });
```

Al vincular el objeto de servicio a un bucket, el objeto de servicio `s3bucket` trata el valor del parámetro `amzn-s3-demo-bucket` como un valor predeterminado que ya no necesita especificarse para operaciones posteriores. Todos los valores de parámetros vinculados se omiten cuando se utiliza el objeto para operaciones donde el valor del parámetro no se puede aplicar. Puede anular este parámetro vinculado cuando hace llamadas en el objeto de servicio, especificando un nuevo valor. 

```
var s3bucket = new AWS.S3({ params: {Bucket: 'amzn-s3-demo-bucket'}, apiVersion: '2006-03-01' });
s3bucket.getObject({Key: 'keyName'});
// ...
s3bucket.getObject({Bucket: 'amzn-s3-demo-bucket3', Key: 'keyOtherName'});
```

Los detalles sobre los parámetros disponibles para cada método se encuentran en la referencia de la API.

# Registro de llamadas del AWS SDK para JavaScript
<a name="logging-sdk-calls"></a>

El AWS SDK para JavaScript dispone de un registrador integrado, por lo que puede registrar las llamadas a la API que realiza con el SDK para JavaScript.

Para activar el registrador e imprimir las entradas de registro en la consola, añada la siguiente instrucción al código.

```
AWS.config.logger = console;
```

Este es un ejemplo del resultado del registro.

```
[AWS s3 200 0.185s 0 retries] createMultipartUpload({ Bucket: 'amzn-s3-demo-logging-bucket', Key: 'issues_1704' })
```

## Uso de registradores de terceros
<a name="third-party-logger"></a>

También puede utilizar un registrador de terceros, siempre y cuando tenga operaciones `log()` o `write()` para escribir en un servidor o archivo de registro. Debe instalar y configurar su registrador personalizado siguiendo las instrucciones indicadas para poder utilizarlo con el SDK para JavaScript.

Logplease es un de estos registradores que se pueden utilizar en scripts de navegador o en Node.js. En Node.js, puede configurar logplease para escribir entradas de registro en un archivo de registro. También puede usarlo con webpack.

Al usar un registrador de terceros, establezca todas las opciones antes de asignar el registrador a `AWS.Config.logger`. Por ejemplo, el código siguiente especifica un archivo de registro externo y establece el nivel de registro de logplease.

```
// Require AWS Node.js SDK
const AWS = require('aws-sdk')
// Require logplease
const logplease = require('logplease');
// Set external log file option
logplease.setLogfile('debug.log');
// Set log level
logplease.setLogLevel('DEBUG');
// Create logger
const logger = logplease.create('logger name');
// Assign logger to SDK
AWS.config.logger = logger;
```

Para obtener más información acerca de logplease, consulte la sección del [registrador de JavaScript sencillo logplease](https://github.com/haadcode/logplease) en GitHub.

# Llamadas asíncronas a servicios
<a name="calling-services-asynchronously"></a>

Todas las solicitudes que se realizan a través del SDK son asíncronas. Es importante recordarlo cuando se escriben scripts de navegador. La ejecución de JavaScript en un navegador web normalmente tiene un solo subproceso de ejecución. Después de realizar una llamada asíncrona a un servicio de AWS, el script de navegador continúa ejecutándose y, en el proceso, puede intentar ejecutar código que dependa de ese resultado asíncrono antes de volver.

La realización de llamadas asíncronas a un servicio de AWS incluye la administración de dichas llamadas de modo que su código no intente utilizar datos antes de que estos estén disponibles. En los temas de esta sección se explica la necesidad de administrar llamadas asíncronas y técnicas diferentes de detalles que puede utilizar para administrarlas.

**Topics**
+ [Administración de llamadas asíncronas](making-asynchronous-calls.md)
+ [Uso de una función de devolución de llamada anónima](using-a-callback-function.md)
+ [Uso de un objeto de un agente de escucha de eventos de objetos de solicitud](using-a-response-event-handler.md)
+ [Uso de async/await](using-async-await.md)
+ [Uso de promesas de JavaScript](using-promises.md)

# Administración de llamadas asíncronas
<a name="making-asynchronous-calls"></a>

Por ejemplo, la página de inicio de un sitio web de e-commerce permite iniciar sesión a los clientes que regresan. Parte del beneficio para los clientes que inician sesión es que, después de iniciar sesión, el sitio se personaliza a sí mismo para adaptarse a sus preferencias concretas. Para que esto suceda:

1. El cliente tiene que iniciar sesión y validarse con sus credenciales de inicio de sesión.

1. Las preferencias del cliente se solicitan a partir de una base de datos del cliente.

1. La base de datos proporciona las preferencias del cliente que se utilizan para personalizar el sitio antes de que se cargue la página.

Si dichas tareas se ejecutan de forma síncrona, cada una tiene que finalizar antes de que la siguiente pueda comenzar. La página web no puede acabar de cargarse hasta que no lleguen las preferencias del cliente desde la base de datos. Sin embargo, después de que la consulta de la base de datos se envíe al servidor, la recepción de los datos del cliente se puede retrasar o incluso generar errores debido a atascos en la red, un tráfico de base de datos excepcionalmente alto o una conexión de dispositivo móvil de mala calidad.

Para evitar que el sitio web se congele en estas condiciones, llame a la base de datos de forma asíncrona. Después de que se ejecute la llamada a la base de datos y se envíe su solicitud asíncrona, el código sigue ejecutándose según lo previsto. Si no administra correctamente la respuesta de una llamada asíncrona, el código puede intentar utilizar información que espera recibir de la base de datos cuando dichos datos todavía no están disponibles.

![\[Diferencia entre la ejecución síncrona y la ejecución asíncrona.\]](http://docs.aws.amazon.com/es_es/sdk-for-javascript/v2/developer-guide/images/async-vs-sync.png)


# Uso de una función de devolución de llamada anónima
<a name="using-a-callback-function"></a>

Cada método de objeto de servicio que crea un objeto `AWS.Request` puede aceptar una función de devolución de llamada anónima como último parámetro. La firma de dicha función de devolución de llamada es:

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

Esta función de devolución de llamada se ejecuta cuando se devuelve una respuesta correcta o datos de error. Si la llamada al método se realiza correctamente, el contenido de la respuesta está disponible en la función de devolución de llamada en el parámetro `data`. Si la llamada no se realiza correctamente, se proporcionan los detalles sobre el error en el parámetro `error`.

Normalmente el código contenido en la función de devolución de llamada realiza una prueba para detectar errores. Si el resultado de la prueba devuelve errores, los procesará. Si no se devuelve ningún error, el código recuperará los datos de la respuesta en el parámetro `data`. La forma básica de la función de devolución de llamada es similar a la de este ejemplo.

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

En el ejemplo anterior, los detalles del error o de los datos devueltos se registran en la consola. A continuación se muestra un ejemplo que muestra una función de devolución de llamada transferida como parte de una llamada a un método en un objeto de servicio.

```
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
  }
});
```

## Acceso a los objetos de solicitud y respuesta
<a name="access-request-response"></a>

Dentro de la función de devolución de llamada, la palabra clave de JavaScript `this` se refiere al objeto `AWS.Response` subyacente para la mayoría de los servicios. En el ejemplo siguiente, la propiedad `httpResponse` de un objeto `AWS.Response` se utiliza dentro de una función de devolución de llamada para registrar los datos de respuesta sin procesar y los encabezados para ayudar con la depuración.

```
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
  }
});
```

Además, debido a que el objeto `AWS.Response` tiene una propiedad `Request` que contiene la `AWS.Request` que se ha enviado a través de la llamada al método original, también puede obtener acceso a los detalles de la solicitud que se realizó.

# Uso de un objeto de un agente de escucha de eventos de objetos de solicitud
<a name="using-a-response-event-handler"></a>

Si no crea ni transfiere una función de devolución de llamada anónima como parámetro cuando llama a un método de objeto de servicio, la llamada al método genera un objeto `AWS.Request` que debe enviarse manualmente usando su método `send`.

Para procesar la respuesta, debe crear un agente de escucha de eventos para que el objeto `AWS.Request` registre una función de devolución de llamada para la llamada al método. En el siguiente ejemplo se muestra cómo crear el objeto `AWS.Request` para llamar a un método de objeto de servicio y al agente de escucha de eventos para que la devolución sea correcta.

```
// 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();
```

Una vez que se ha llamado al método `send` en el objeto `AWS.Request`, el controlador de eventos se ejecuta cuando el objeto de servicio recibe un objeto `AWS.Response`.

Para obtener más información acerca del objeto `AWS.Request`, consulte [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) en la referencia de la API. Para obtener más información acerca del objeto `AWS.Response`, consulte [Uso del objeto de respuesta](the-response-object.md) o [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html) en la referencia de la API.

## Encadenar varias devoluciones de llamadas
<a name="response-chaining-callbacks"></a>

Puede registrar varias devoluciones de llamada en cualquier objeto de solicitud. Se pueden registrar varias devoluciones de llamada para diferentes eventos o para el mismo evento. También puede encadenar devoluciones de llamadas, tal y como se muestra en el siguiente ejemplo.

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

## Eventos de finalización de objetos de solicitud
<a name="request-object-completion-events"></a>

El objeto `AWS.Request` plantea estos eventos de finalización en función de la respuesta de cada método de operación de servicio:
+ `success`
+ `error`
+ `complete`

Puede registrar una función de devolución de llamada en respuesta a cualquiera de estos eventos. Para obtener una lista completa de todos los eventos de objetos de solicitud, consulte [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) en la referencia de la API.

### El evento success
<a name="request-success-event"></a>

El evento `success` se plantea cuando se recibe una respuesta de éxito desde el objeto de servicio. Aquí se muestra cómo registrar una función de devolución de llamada para este evento.

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

La respuesta proporciona una propiedad `data` que contiene los datos de respuesta serializada del servicio. Por ejemplo, la siguiente llamada al método `listBuckets` del objeto de servicio de Amazon S3

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

devuelve la respuesta y luego imprime el siguiente contenido de la propiedad `data` a la consola.

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

### El evento error
<a name="request-error-event"></a>

El evento `error` se plantea cuando se recibe una respuesta de error desde el objeto de servicio. Aquí se muestra cómo registrar una función de devolución de llamada para este evento.

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

Cuando el evento `error` se produce, el valor de la propiedad `data` de la respuesta es `null` y la propiedad `error` contiene los datos del error. El objeto `error` asociado se transfiere como primer parámetro a la función de devolución de llamada registrada. Por ejemplo, el código siguiente:

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

devuelve el error y luego imprime los datos de error siguientes a la consola.

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

### El evento complete
<a name="request-complete-event"></a>

El evento `complete` se produce cuando una llamada al objeto de servicio ha terminado, independientemente de si la llamada se traduce en éxito o en error. Aquí se muestra cómo registrar una función de devolución de llamada para este evento.

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

Utilice la devolución de llamada del evento `complete` para gestionar cualquier limpieza de solicitud que debe ejecutarse independientemente de si el resultado ha sido un éxito o un error. Si utiliza los datos de respuesta dentro de una devolución de llamada para el evento `complete`, en primer lugar, compruebe las propiedades `response.data` o `response.error` antes de intentar obtener acceso a una de ellas, tal y como se muestra en el siguiente ejemplo.

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

## Eventos de HTTP de objetos de solicitud
<a name="request-object-http-events"></a>

El objeto `AWS.Request` plantea estos eventos HTTP en función de la respuesta de cada método de operación de servicio:
+ `httpHeaders`
+ `httpData`
+ `httpUploadProgress`
+ `httpDownloadProgress`
+ `httpError`
+ `httpDone`

Puede registrar una función de devolución de llamada en respuesta a cualquiera de estos eventos. Para obtener una lista completa de todos los eventos de objetos de solicitud, consulte [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) en la referencia de la API.

### El evento httpHeaders
<a name="request-httpheaders-event"></a>

El evento `httpHeaders` se produce cuando el servidor remoto envía los encabezados. Aquí se muestra cómo registrar una función de devolución de llamada para este evento.

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

El parámetro `statusCode` para la función de devolución de llamada es el código de estado HTTP. El parámetro `headers` contiene los encabezados de la respuesta.

### El evento httpData
<a name="request-httpdata-event"></a>

El `httpData` evento se plantea para transmitir en streaming los paquetes de datos de respuesta desde el servicio. Aquí se muestra cómo registrar una función de devolución de llamada para este evento.

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

Este evento se suele utilizar para recibir respuestas de gran tamaño en fragmentos cuando cargar toda la respuesta en la memoria no es práctico. Este evento tiene un parámetro `chunk` adicional que contiene una parte de los datos reales del servidor.

Si registra una devolución de llamada para el evento `httpData`, la propiedad `data` de la respuesta contiene toda la salida serializada de la solicitud. Debe eliminar el agente de escucha `httpData` predeterminado si no tiene la cantidad adicional de memoria y análisis adicional para los controladores integrados.

### Los eventos httpDownloadProgress y httpUploadProgress
<a name="request-httpupload-download-progress-event"></a>

El evento `httpUploadProgress` se produce cuando la solicitud HTTP ha cargado más datos. Igualmente, el evento `httpDownloadProgress` se produce cuando la solicitud HTTP ha descargado más datos. Aquí se muestra cómo registrar una función de devolución de llamada para estos eventos.

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

El parámetro `progress` para la función de devolución de llamada contiene un objeto con los bytes cargados y totales de la solicitud.

### El evento httpError
<a name="request-httperror-event"></a>

El evento `httpError` se produce cuando la solicitud HTTP genera un error. Aquí se muestra cómo registrar una función de devolución de llamada para este evento.

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

El parámetro `error` para la función de devolución de llamada contiene el error que se generó.

### El evento httpDone
<a name="request-httpdone-event"></a>

El evento `httpDone` se produce cuando el servidor termina el envío de datos. Aquí se muestra cómo registrar una función de devolución de llamada para este evento.

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

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

Puede utilizar el patrón `async/await` en sus llamadas al AWS SDK para JavaScript. La mayoría de las funciones que aceptan una devolución de llamada no devuelven una promesa. Como solo se utilizan funciones `await` que devuelven una promesa, para utilizar el patrón `async/await` hay que encadenar el método `.promise()` hasta el final de la llamada y eliminar la devolución de llamada.

En el siguiente ejemplo, se usa async/await para enumerar todas las tablas de Amazon DynamoDB en `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();
```

**nota**  
 No todos los navegadores admiten async/await. Consulte las [funciones asíncronas](https://caniuse.com/#feat=async-functions) para obtener una lista de navegadores compatibles con async/await. 

# Uso de promesas de JavaScript
<a name="using-promises"></a>

El método `AWS.Request.promise` proporciona una forma de llamar a una operación de servicio y administrar el flujo asíncrono en lugar de utilizar devoluciones de llamada. En Node.js y en los scripts de navegador, se devuelve un objeto `AWS.Request` cuando se llama a una operación de servicio sin una función de devolución de llamada. Puede llamar al método `send` de la solicitud para realizar la llamada de servicio.

Sin embargo, `AWS.Request.promise` comienza inmediatamente la llamada de servicio y devuelve una promesa que se cumple con la propiedad `data` de la respuesta o se rechaza con la propiedad `error` de la respuesta.

```
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 */
  }
);
```

En el siguiente ejemplo se devuelve una promesa que se cumple con un objeto `data` o se rechaza con un objeto `error`. Con el uso de las promesas, una única devolución de llamada no es responsable de la detección de errores. En su lugar, se llama a la devolución de llamada correcta en función del éxito o el error de una solicitud.

```
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);
});
```

## Coordinación de varias promesas
<a name="multiple-promises"></a>

En algunas situaciones, el código debe realizar varias llamadas asíncronas que requieren acción solo cuando todas han tenido una devolución correcta. Si administra estas llamadas a métodos asíncronas individuales con promesas, puede crear una promesa adicional que utilice el método `all`. Este método cumple esta promesa paraguas en el momento en que transfiere la matriz de promesas al método siempre y cuando dicha matriz de promesas se cumpla. Se transfiere a la función de devolución de llamada una matriz de los valores de las promesas que se transfieren al método `all`.

En el siguiente ejemplo, una función de Lambda tiene que realizar tres llamadas asíncronas a Amazon DynamoDB, pero solo puede completarse después de que las promesas para cada llamada se cumplan.

```
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);
});
```

## Compatibilidad del navegador y Node.js con las promesas
<a name="browser-node-promise-support"></a>

La compatibilidad con promesas de JavaScript (ECMAScript 2015) depende del motor y la versión de JavaScript en los que se ejecuta el código. Para ayudar a determinar la compatibilidad con las promesas de JavaScript en cada entorno donde el código necesita ejecutarse, consulte la [tabla de compatibilidad ECMAScript](https://compat-table.github.io/compat-table/es6/) en GitHub.

## Uso de otras implementaciones de promesas
<a name="using-other-promise-implementations"></a>

Además de la implementación de promesas nativa de ECMAScript 2015, también puede utilizar bibliotecas de promesas de terceros, como:
+ [bluebird](http://bluebirdjs.com)
+ [RSVP](https://github.com/tildeio/rsvp.js/)
+ [Q](https://github.com/kriskowal/q)

Estas bibliotecas de promesas opcionales pueden ser útiles si necesita que el código se ejecute en entornos que no admitan la implementación de promesas nativas en ECMAScript 5 y en ECMAScript de 2015.

Para utilizar una biblioteca de promesas de terceros, establezca una dependencia de promesas en el SDK llamando al método `setPromisesDependency` del objeto de configuración global. En los scripts de navegador, asegúrese de cargar la biblioteca de promesas de terceros antes de cargar el SDK. En el siguiente ejemplo, el SDK está configurado para utilizar la implementación en la biblioteca de promesas bluebird.

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

Para volver a utilizar la implementación de promesas nativa del motor de JavaScript, vuelva a llamar a `setPromisesDependency` y transfiera `null` en vez de un nombre de biblioteca.

# Uso del objeto de respuesta
<a name="the-response-object"></a>

Después de llamar a un método objeto de servicio, este devuelve un objeto `AWS.Response` transfiriéndolo a su función de devolución de llamada. Puede obtener acceso al contenido de la respuesta a través de las propiedades del objeto `AWS.Response`. Puede usar dos propiedades del objeto `AWS.Response` para obtener acceso al contenido de la respuesta:
+ `data`Propiedad 
+ `error`Propiedad 

Cuando se utiliza el mecanismo de devolución de llamada estándar, estos dos propiedades se proporcionan como parámetros en la función de devolución de llamada anónima tal y como se muestra en el siguiente ejemplo.

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

## Acceso a los datos devueltos en el objeto de respuesta
<a name="response-data-property"></a>

La propiedad `data` del objeto `AWS.Response` contiene los datos serializados devueltos por la solicitud de servicio. Cuando la solicitud se realiza correctamente, la propiedad `data` incluye un objeto que contiene un mapa a los datos devueltos. La propiedad `data` puede ser un valor nulo si se produce un error.

A continuación se muestra un ejemplo llamada al método `getItem` de una tabla de DynamoDB para recuperar el nombre de un archivo de imagen y utilizarlo como parte de un juego.

```
// Initialize parameters needed to call DynamoDB
var slotParams = {
    Key : {'slotPosition' : {N: '0'}},
    TableName : 'slotWheels',
    ProjectionExpression: 'imageFile'
};

// prepare request object for call to DynamoDB
var request = new AWS.DynamoDB({region: 'us-west-2', apiVersion: '2012-08-10'}).getItem(slotParams);
// log the name of the image file to load in the slot machine
request.on('success', function(response) {
    // logs a value like "cherries.jpg" returned from DynamoDB
    console.log(response.data.Item.imageFile.S);
});
// submit DynamoDB request
request.send();
```

En este ejemplo, la tabla de DynamoDB es una búsqueda de imágenes que muestra los resultados de una máquina tragaperras según lo especificado por los parámetros en `slotParams`.

Tras una llamada del método `getItem` realizada correctamente, la propiedad `data` del objeto `AWS.Response` contiene un objeto `Item` devuelto por DynamoDB. El acceso a los datos devueltos se efectúa de acuerdo con el parámetro `ProjectionExpression` de la solicitud, que en este caso significa el miembro `imageFile` del objeto `Item`. Debido a que el miembro `imageFile` contiene un valor de cadena, el usuario obtiene acceso al nombre de archivo de la misma imagen a través del valor del elemento secundario `S` de `imageFile`.

## Paginación por los datos devueltos
<a name="response-paged-data"></a>

En ocasiones el contenido de la propiedad `data` que una solicitud de servicio devuelve abarca varias páginas. Puede obtener acceso a la siguiente página de datos llamando al método `response.nextPage`. Este método envía una nueva solicitud. La respuesta de la solicitud se puede capturar con una devolución de llamada o con agentes de escucha de éxito y error.

Puede comprobar si los datos devueltos por una solicitud de servicio tienen páginas de datos adicionales llamando al método `response.hasNextPage`. Este método devuelve un valor booleano para indicar si la llamada a `response.nextPage` devuelve datos adicionales.

```
s3.listObjects({Bucket: 'bucket'}).on('success', function handlePage(response) {
    // do something with response.data
    if (response.hasNextPage()) {
        response.nextPage().on('success', handlePage).send();
    }
}).send();
```

## Acceso a información de error desde un objeto de respuesta
<a name="response-error-property"></a>

La propiedad `error` del objeto `AWS.Response` contiene los datos de error disponibles en caso de que se produzca un error de servicio o un error de transferencia. El error devuelto adopta el siguiente formato.

```
{ code: 'SHORT_UNIQUE_ERROR_CODE', message: 'a descriptive error message' }
```

En caso de que se produzca un error, el valor de la propiedad `data` es `null`. Si gestiona eventos que pueden estar en un estado de error, compruebe siempre si la propiedad `error` se estableció antes de intentar obtener acceso al valor de la propiedad `data`.

## Acceso al objeto de solicitud de origen
<a name="response-request-property"></a>

La propiedad `request` proporciona acceso al objeto `AWS.Request` de origen. Puede ser útil para hacer referencia al objeto `AWS.Request` original para obtener acceso a los parámetros originales que ha enviado. En el ejemplo siguiente, la propiedad `request` se utiliza para obtener acceso al parámetro `Key` de la solicitud de servicio original.

```
s3.getObject({Bucket: 'bucket', Key: 'key'}).on('success', function(response) {
   console.log("Key was", response.request.params.Key);
}).send();
```

# Uso de JSON
<a name="working-with-json"></a>

JSON es un formato para el intercambio de datos que pueden leer tanto humanos como las máquinas. Aunque el nombre JSON es el acrónimo de *JavaScript Object Notation (notación de objetos JavaScript)*, el formato de JSON es independiente de cualquier lenguaje de programación.

El SDK para JavaScript utiliza JSON para enviar datos a objetos de servicio cuando realiza solicitudes y recibe datos de objetos de servicio como JSON. Para obtener más información sobre JSON, consulte [json.org](https://json.org).

![\[Presentación del formato y las partes generales de JSON.\]](http://docs.aws.amazon.com/es_es/sdk-for-javascript/v2/developer-guide/images/json-format.png)


JSON representa los datos de dos formas:
+ Un *objeto*, que es una colección sin ordenar de pares de nombre-valor. Un objeto se define entre las llaves izquierda (`{`) y derecha (`}`). Cada par de nombre-valor comienza por el nombre, seguido de dos puntos, seguido del valor. Los pares de nombre-valor están separados por comas.
+ Una *matriz*, que es una colección ordenada de valores. Una matriz se define entre los corchetes izquierdo (`[`) y derecho (`]`). Los elementos de la matriz están separados por comas.

A continuación, se muestra un ejemplo de un objeto JSON que contiene una matriz de objetos en la que los objetos representan las naipes de un juego de cartas. Cada carta está definida con dos pares de nombre-valor, uno que especifica un valor único para identificar la carta y otra que especifica una dirección URL que apunta a la imagen de la carta correspondiente.

```
var cards = [{"CardID":"defaultname", "Image":"defaulturl"},
  {"CardID":"defaultname", "Image":"defaulturl"},
  {"CardID":"defaultname", "Image":"defaulturl"},
  {"CardID":"defaultname", "Image":"defaulturl"},
  {"CardID":"defaultname", "Image":"defaulturl"}];
```

## Parámetros de JSON como objeto de servicio
<a name="json-as-parameters-passed"></a>

A continuación, se muestra un ejemplo de JSON sencillo que se utiliza para definir los parámetros de una llamada a un objeto de servicio de Lambda.

```
var pullParams = {
   FunctionName : 'slotPull',
   InvocationType : 'RequestResponse',
   LogType : 'None'
};
```

El objeto `pullParams` se define mediante tres pares de nombre-valor, separados por comas e incluidos entre llaves (izquierda y derecha). Cuando se proporcionan parámetros a una llamada de método de objeto de servicio, los nombres se determinan mediante nombres de parámetros para el método de objeto de servicio al que tiene previsto llamar. Al invocar una función de Lambda, `FunctionName`, `InvocationType` y `LogType` son los parámetros que se utilizan para llamar al método `invoke` de un objeto de servicio de Lambda.

Cuando transfiera parámetros a una llamada de método de objeto de servicio, proporcione el objeto JSON a la llamada al método, tal y como se muestra en el siguiente ejemplo de invocación a una función de Lambda.

```
lambda = new AWS.Lambda({region: 'us-west-2', apiVersion: '2015-03-31'});
// create JSON object for service call parameters
var pullParams = {
   FunctionName : 'slotPull',
   InvocationType : 'RequestResponse',
   LogType : 'None'
};                
// invoke Lambda function, passing JSON object
lambda.invoke(pullParams, function(err, data) {
   if (err) {
      console.log(err);
   } else {
      console.log(data);
   }
});
```

## Devolución de datos como JSON
<a name="json-as-returned-data"></a>

JSON ofrece una forma estándar de transferir datos entre partes de una aplicación que necesitan enviar varios valores al mismo tiempo. Los métodos de clases de cliente en la API suelen devolver JSON en el parámetro `data` que se transfiere a sus funciones de devolución de llamada. Por ejemplo, a continuación se muestra una llamada al método `getBucketCors` de la clase de cliente de Amazon S3.

```
// call S3 to retrieve CORS configuration for selected bucket
s3.getBucketCors(bucketParams, function(err, data) {
  if (err) {
    console.log(err);
  } else if (data) {
    console.log(JSON.stringify(data));
  }
});
```

El valor de `data` es un objeto JSON; en este ejemplo, JSON que describe la configuración CORS actual para un bucket de Amazon S3 especificado.

```
{
   "CORSRules": [
      {
          "AllowedHeaders":["*"],
          "AllowedMethods":["POST","GET","PUT","DELETE","HEAD"],
          "AllowedOrigins":["*"],
          "ExposeHeaders":[],
          "MaxAgeSeconds":3000
      }
   ]
}
```

# Estrategia de reintentos en la versión 2 de AWS SDK para JavaScript
<a name="retry-strategy"></a>

Numerosos componentes de una red, como los servidores DNS, los conmutadores o los balanceadores de carga, entre otros, pueden generar errores en cualquier punto de la vida de una solicitud determinada. La técnica habitual para abordar estas respuestas de error en un entorno de red consiste en implementar los reintentos en la aplicación cliente. Esta técnica aumenta la fiabilidad de la aplicación y reduce los costos operativos para el desarrollador. AWS Los SDK implementan una lógica de reintentos automatizados para las solicitudes de AWS.

## Comportamiento de reintentos basado en el retroceso exponencial
<a name="retry-behavior"></a>

La versión 2 de AWS SDK para JavaScript implementa la lógica de reintentos mediante el [retroceso exponencial con fluctuación completa](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/#Jitter) para obtener un mejor control del flujo. El retardo exponencial se basa en la idea de utilizar tiempos de espera progresivamente más largos entre reintentos para las respuestas a errores consecutivos. La fluctuación (retardo aleatorio) se utiliza para evitar colisiones sucesivas. 

### Prueba del retardo de reintentos en la versión 2
<a name="w2aac18c37b5b5"></a>

Para probar el retardo de reintentos en la versión 2, se ha actualizado el código en [node\$1modules/aws-sdk/lib/event\$1listeners.js](https://github.com/aws/aws-sdk-js/blob/master/lib/event_listeners.js#L588) en `console.log` al valor presente en la variable delay de la siguiente manera: 

```
// delay < 0 is a signal from customBackoff to skip retries
if (willRetry && delay >= 0) {
  resp.error = null;
  console.log('retry delay: ' + delay);
  setTimeout(done, delay);
} else {
  done();
}
```

#### Retardos de reintentos con la configuración predeterminada
<a name="w2aac18c37b5b5b7"></a>

Puede probar el retardo de cualquier operación en los clientes del SDK de AWS. Llamamos a la operación `listTables` en un cliente de DynamoDB con el siguiente código:

```
import AWS from "aws-sdk";

const region = "us-east-1";
const client = new AWS.DynamoDB({ region });
await client.listTables({}).promise();
```

Para probar los reintentos, simulamos `NetworkingError` mediante la desconexión de Internet del dispositivo que ejecuta el código de prueba. También puede configurar el proxy para que devuelva un error personalizado.

Al ejecutar el código, puede ver que el retardo de reintentos mediante el retroceso exponencial con fluctuación es como sigue:

```
retry delay: 7.39361151766359
retry delay: 9.0672860785882
retry delay: 134.89340825668168
retry delay: 398.53559817403965
retry delay: 523.8076165896343
retry delay: 1323.8789643058465
```

Como el reintento utiliza la fluctuación, obtendrá valores diferentes en la ejecución del código de ejemplo.

#### Retardos de reintentos con base personalizada
<a name="w2aac18c37b5b5b9"></a>

La versión 2 de AWS SDK para JavaScript permite pasar un número base personalizado de milisegundos para utilizarlo en el retroceso exponencial para los reintentos de la operación. Está predeterminado a 100 ms para todos los servicios excepto DynamoDB, donde está predeterminado a 50 ms.

Probamos los reintentos con una base personalizada de 1000 ms de la siguiente manera:

```
...
const client = new AWS.DynamoDB({ region, retryDelayOptions: { base: 1000 } });
...
```

Simulamos `NetworkingError` mediante la desconexión de Internet del dispositivo que ejecuta el código de prueba. Puede ver que los valores para el retardo de reintentos son más altos en comparación con la ejecución anterior, en la que el valor predeterminado era de 50 o 100 ms.

```
retry delay: 356.2841549924913
retry delay: 1183.5216495444615
retry delay: 2266.997988094194
retry delay: 1244.6948354966453
retry delay: 4200.323030066383
```

Como el reintento utiliza la fluctuación, obtendrá valores diferentes en la ejecución del código de ejemplo.

#### Retardos de reintentos con algoritmo de retroceso personalizado
<a name="w2aac18c37b5b5c11"></a>

La versión 2 de AWS SDK para JavaScript también permite pasar una función de retroceso personalizada que acepta un recuento de reintentos y un error y devuelve la cantidad de tiempo que se retrasará en milisegundos. Si el resultado es un valor negativo distinto de cero, no se realizarán más intentos de reintentos.

Probamos la función de retroceso personalizada que utiliza el retroceso lineal con un valor base de 200 ms de la siguiente manera:

```
...
const client = new AWS.DynamoDB({
  region,
  retryDelayOptions: { customBackoff: (count, error) => (count + 1) * 200 },
});
...
```

Simulamos `NetworkingError` mediante la desconexión de Internet del dispositivo que ejecuta el código de prueba. Puede ver que los valores para el retardo de reintentos son múltiplos de 200.

```
retry delay: 200
retry delay: 400
retry delay: 600
retry delay: 800
retry delay: 1000
```