

O AWS SDK para JavaScript v2 chegou ao fim do suporte. Recomendamos migrar para o [AWS SDK para JavaScript v3](https://docs.aws.amazon.com//sdk-for-javascript/v3/developer-guide/). Para ver detalhes e informações sobre como migrar, consulte este [anúncio](https://aws.amazon.com/blogs//developer/announcing-end-of-support-for-aws-sdk-for-javascript-v2/).

# Chamar serviços assincronamente
<a name="calling-services-asynchronously"></a>

Todas as solicitações feitas por meio do SDK são assíncronas. É importante ter isso em mente ao gravar scripts do navegador. O JavaScript executado em um navegador normalmente tem apenas um único thread de execução. Depois de fazer uma chamada assíncrona para um serviço da AWS, o script do navegador continua em execução e, nesse processo, pode tentar executar um código que depende do resultado assíncrono antes que tenha retorno.

Fazer chamadas assíncronas para gerenciar um serviço da AWS inclui gerenciar essas chamadas para que seu código não tente usar dados antes de serem disponibilizados. Os tópicos desta seção explicam a necessidade de gerenciar chamadas assíncronas e detalha diferentes técnicas que você pode usar para gerenciá-las.

**Topics**
+ [Gerenciar chamadas assíncronas](making-asynchronous-calls.md)
+ [Usar uma função de retorno de chamada anônimo](using-a-callback-function.md)
+ [Usar um listener de evento do objeto de solicitação](using-a-response-event-handler.md)
+ [Usar async/await](using-async-await.md)
+ [Usar as promessas do JavaScript](using-promises.md)

# Gerenciar chamadas assíncronas
<a name="making-asynchronous-calls"></a>

Por exemplo, a página inicial de um site de comércio eletrônico permite que os clientes que retornam façam login. Parte do benefício para os clientes que fazem login é que, depois de fazerem-no, o site se personaliza de acordo com suas preferências específicas. Para fazer isso acontecer:

1. O cliente deve fazer login e ser validado com suas credenciais de login.

1. As preferências do cliente são solicitadas a banco de dados de clientes.

1. O banco de dados fornece as preferências do cliente, que são usadas para personalizar o site antes que a página carregue.

Se essas tarefas forem executadas de forma síncrona, cada uma delas deverá terminar antes de a seguinte começar. A página da web não terminaria de carregar até que as preferências do cliente fossem apresentadas pelo banco de dados. No entanto, após a consulta de banco de dados ser enviada ao servidor, o recebimento dos dados do cliente pode ser atrasado ou até mesmo falhar devido a gargalos da rede, tráfego excepcionalmente alto no banco de dados ou conexão ruim nos dispositivos móveis.

Para evitar que o site congele sob essas condições, chame o banco de dados de forma assíncrona. Depois de a chamada do banco de dados ser executada, enviando sua solicitação assíncrona, o código continuará a ser executado conforme o esperado. Se você não gerir adequadamente a resposta de uma chamada assíncrona, o código poderá tentar usar informações que espera de volta do banco de dados quando esses dados ainda não estiverem disponíveis.

![\[Mostrando a diferença entre a execução síncrona e a execução assíncrona.\]](http://docs.aws.amazon.com/pt_br/sdk-for-javascript/v2/developer-guide/images/async-vs-sync.png)


# Usar uma função de retorno de chamada anônimo
<a name="using-a-callback-function"></a>

Cada método de objeto de serviço que cria um objeto `AWS.Request` pode aceitar uma função de retorno de chamada anônimo como último parâmetro. A assinatura dessa função de retorno de chamada é:

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

Essa função de retorno de chamada é executada ao se retornar uma resposta bem-sucedida ou dados de erro. Se a chamada do método for bem-sucedida, o conteúdo da resposta estará disponível para a função de retorno de chamada no parâmetro `data`. Se a chamada não for bem-sucedida, os detalhes sobre a falha são fornecidos no parâmetro `error`.

Normalmente o código dentro da função de retorno de chamada testa um erro, que ele processa, caso seja retornado um erro. Se o erro não for retornado, o código recuperará os dados na resposta pelo parâmetro `data`. O formato básico da função de retorno de chamada é semelhante a este exemplo.

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

No exemplo anterior, os detalhes do erro ou dos dados retornados são registrados no console. Veja a seguir um exemplo que mostra uma função de retorno de chamada passada como parte da chamada de um método em um objeto de serviço.

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

## Acessar os objetos de solicitação e resposta
<a name="access-request-response"></a>

Dentro da função de retorno de chamada, a palavra-chave `this` do JavaScript refere-se ao objeto `AWS.Response` subjacente à maioria dos serviços. No exemplo a seguir, a propriedade `httpResponse` de um objeto `AWS.Response` é usada dentro de uma função de retorno de chamada para registrar os dados de resposta brutos e os cabeçalhos para ajudar com a depuração.

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

Além disso, como o objeto `AWS.Response` tem uma propriedade `Request` que contém o `AWS.Request` enviado pela chamada do método original, você também pode acessar os detalhes da solicitação que foi feita.

# Usar um listener de evento do objeto de solicitação
<a name="using-a-response-event-handler"></a>

Se você não criar e passar uma função de retorno de chamada anônimo como parâmetro quando chamar o método de objeto de um serviço, a chamada do método gera um objeto `AWS.Request`, que deve ser enviado manualmente usando o método `send`.

Para processar a resposta, você deve criar um listener de evento para o objeto `AWS.Request` para registrar uma função de retorno de chamada para a chamada do método. O exemplo a seguir mostra como criar o objeto `AWS.Request` para chamar um método de objeto de serviço e o listener do evento para uma devolução bem-sucedida.

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

Depois de chamado o método `send` no objeto `AWS.Request`, o manipulador de eventos é executado quando o objeto de serviço recebe um objeto `AWS.Response`.

Para obter mais informações sobre o objeto `AWS.Request`, consulte [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) na Referência de API. Para obter mais informações sobre o objeto `AWS.Response`, consulte [Usar o objeto de resposta](the-response-object.md) ou [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Response.html) na Referência de API.

## Encadear vários retornos de chamada
<a name="response-chaining-callbacks"></a>

Você pode registrar vários retornos de chamada em qualquer objeto de solicitação. É possível registrar vários retornos de chamada para diferentes eventos ou para o mesmo evento. Além disso, você pode encadear retornos de chamada conforme exibido no exemplo a seguir.

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

## Eventos de conclusão do objeto de solicitação
<a name="request-object-completion-events"></a>

O objeto `AWS.Request` gera esses eventos de conclusão com base na resposta de cada método de operação de serviço:
+ `success`
+ `error`
+ `complete`

Você pode registrar uma função de retorno de chamada em resposta a qualquer um desses eventos. Para obter uma lista completa de todos os eventos de objeto da solicitação, consulte [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) na Referência da API.

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

O evento `success` é gerado após uma resposta bem-sucedida recebida do objeto de serviço. Veja aqui como registrar uma função de retorno de chamada para esse evento.

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

A resposta fornece uma propriedade `data`, que contém os dados de resposta serializada do serviço. Por exemplo, a chamada a seguir para o método `listBuckets` do objeto de serviço do Amazon S3.

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

retorna a resposta e imprime os conteúdos da propriedade `data` a seguir no console.

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

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

O evento `error` é gerado após uma resposta de erro recebida do objeto de serviço. Veja aqui como registrar uma função de retorno de chamada para esse evento.

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

Quando o evento `error` é gerado, o valor da propriedade `data` da resposta é `null` e a propriedade `error` contém os dados do erro. O objeto `error` associado é passado como o primeiro parâmetro para a função de retorno de chamada registrada. Por exemplo, o seguinte código:

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

retorna o erro e imprime os seguintes dados de erro no console.

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

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

O evento `complete` é gerado quando uma chamada de objeto de serviço tiver sido concluída, independentemente de ela resultar em sucesso ou erro. Veja aqui como registrar uma função de retorno de chamada para esse evento.

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

Use o retorno de chamada do evento `complete` para lidar com qualquer limpeza de solicitação que precise executar, independentemente de sucesso ou erro. Se você usar dados de resposta dentro de um retorno de chamada para o evento `complete`, primeiro verifique as propriedades `response.data` ou `response.error` para depois tentar acessar qualquer uma delas, conforme mostrado no exemplo a seguir.

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

## Eventos HTTP do objeto da solicitação
<a name="request-object-http-events"></a>

O objeto `AWS.Request` gera esses eventos HTTP com base na resposta de cada método de operação de serviço:
+ `httpHeaders`
+ `httpData`
+ `httpUploadProgress`
+ `httpDownloadProgress`
+ `httpError`
+ `httpDone`

Você pode registrar uma função de retorno de chamada em resposta a qualquer um desses eventos. Para obter uma lista completa de todos os eventos de objeto da solicitação, consulte [https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Request.html) na Referência da API.

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

O evento `httpHeaders` é gerado quando cabeçalhos são enviados pelo servidor remoto. Veja aqui como registrar uma função de retorno de chamada para esse evento.

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

O parâmetro `statusCode` para a função de retorno de chamada é o código de status HTTP. O parâmetro `headers` contém os cabeçalhos de resposta.

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

O evento `httpData` é gerado para transmitir pacotes de dados de resposta do serviço. Veja aqui como registrar uma função de retorno de chamada para esse evento.

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

Esse evento é normalmente usado para receber grandes respostas em blocos quando não for prático carregar toda a resposta na memória. Esse evento tem um parâmetro `chunk` adicional que contém uma parte dos dados reais do servidor.

Se você registrar um retorno de chamada para o evento `httpData`, a propriedade `data` da resposta contém toda a saída serializada para a solicitação. Você deve remover o listener `httpData` padrão se você não tiver custos indiretos de memória e análise sintática adicional para os handlers incorporados.

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

O evento `httpUploadProgress` é gerado quando a solicitação HTTP tiver carregado mais dados. Da mesma forma, o evento `httpDownloadProgress` é gerado quando a solicitação HTTP tiver baixado mais dados. Veja aqui como registrar uma função de retorno de chamada para esses eventos.

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

O parâmetro `progress` para a função de retorno de chamada contém um objeto com os bytes carregados e totais da solicitação.

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

O evento `httpError` é gerado quando a solicitação HTTP falhar. Veja aqui como registrar uma função de retorno de chamada para esse evento.

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

O parâmetro `error` para a função de retorno de chamada contém o erro que foi lançado.

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

O evento `httpDone` é gerado quando o servidor terminar de enviar dados. Veja aqui como registrar uma função de retorno de chamada para esse evento.

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

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

Você pode usar o `async/await` padrão em suas chamadas para o AWS SDK para JavaScript. A maioria das funções que recebem um retorno de chamada não retorna uma promessa. Como você usa apenas funções do `await` que retornam uma promessa, para usar o padrão de `async/await`, você precisa encadear o método de `.promise()` até o final da chamada e remover o retorno de chamada.

O exemplo a seguir usa async/await para listar todas as tabelas do Amazon DynamoDB em `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**  
 Nem todos os navegadores oferecem suporte para async/await. Consulte [Funções assíncronas](https://caniuse.com/#feat=async-functions) para obter uma lista de navegadores com suporte para async/await. 

# Usar as promessas do JavaScript
<a name="using-promises"></a>

O método `AWS.Request.promise` fornece uma maneira de chamar uma operação de serviço assíncrona e gerenciar o fluxo em vez de usar retornos de chamada. No Node.js e nos scripts do navegador, um objeto `AWS.Request` é retornado quando a operação de serviço é chamada sem uma função de retorno de chamada. Você pode chamar o método `send` da solicitação para fazer a chamada de serviço.

No entanto, o `AWS.Request.promise` imediatamente começa a chamada de serviço e retorna uma promessa que é cumprida com a propriedade `data` da resposta ou rejeitada com a propriedade `error` da resposta.

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

O exemplo a seguir retorna uma promessa que é atendida com um objeto `data` ou rejeitada com um objeto `error`. Usando promessas, um único retorno de chamada não é responsável por detectar erros. Em vez disso, o retorno de chamada correto é chamado com base no sucesso ou na falha de uma solicitação.

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

## Coordenar várias promessas
<a name="multiple-promises"></a>

Em algumas situações, seu código deve fazer várias chamadas assíncronas que exigem ação somente quando todos tiverem sido retornados com êxito. Se você gerenciar as chamadas individuais do método assíncrono com promessas, pode criar uma promessa adicional que usa o método `all`. Esse método cumpre essa promessa generalista se, e quando, a série de promessas que você passar para o método forem cumpridas. A função de retorno de chamada é transmitida a um array dos valores das promessas passadas para o método `all`.

No exemplo a seguir, uma função do AWS Lambda deve fazer três chamadas assíncronas para Amazon DynamoDB, mas só pode ser concluída após as promessas para cada chamada serem cumpridas.

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

## Suporte de navegador e Node.js para promessas
<a name="browser-node-promise-support"></a>

O suporte para promessas de JavaScript nativo (ECMAScript 2015) depende do mecanismo JavaScript e da versão em que seu código é executado. Para ajudar a determinar o suporte para promessas de JavaScript em cada ambiente onde seu código precisa rodar, consulte a [Tabela Compatibilidade de ECMAScript](https://compat-table.github.io/compat-table/es6/) no GitHub.

## Usando outras implementações de promessa
<a name="using-other-promise-implementations"></a>

Além da implementação de promessa nativa no ECMAScript 2015, você também pode usar bibliotecas de promessa de terceiros, incluindo:
+ [bluebird](http://bluebirdjs.com)
+ [RSVP](https://github.com/tildeio/rsvp.js/)
+ [P](https://github.com/kriskowal/q)

Essas bibliotecas de promessa opcionais podem ser úteis se você precisar que seu código rode em ambientes que não são compatíveis com a implementação de promessa nativa no ECMAScript 5 e no ECMAScript 2015.

Para usar uma biblioteca de promessa de terceiros, defina uma dependência de promessas no SDK chamando o método `setPromisesDependency` do objeto de configuração global. No navegador de scripts, carregue a biblioteca de promessas de terceiros antes de carregar o SDK. No exemplo a seguir, o SDK é configurado para usar a implementação na biblioteca de promessas do bluebird.

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

Para voltar a usar a implementação de promessa nativa do mecanismo JavaScript, chame `setPromisesDependency` novamente, passando um `null` em vez do nome de uma biblioteca.