Como encadear promises

Como encadear promises

Tulio Faria
Tulio Faria31 de agosto de 2017

Na dica de hoje, vamos continuar falando sobre promises. Vou mostrar um detalhe na promise que é bastante interessante: como podemos encadear promises, ou seja, vincular uma promise à outra.

Para poder fazer isso funcionar, vamos começar importando nosso tão usado FS, já que ele é sempre uma chave para isso e em seguida vamos criar uma função readFile, que vai ser uma arrow function. Nós passamos para ele um path de um arquivo e ele vai retornar uma promise nova:

const fs = require('fs')

const readFile = (file) => {
  return new Promise((resolve, reject) => {
    fs.readFile(file, (err, contents) => {
      if (err) {
        reject(err)
      } else {
        resolve(contents.toString())
      }
    })
  })
}

Consideramos que quem vai receber o conteúdo da nova promise queira esse conteúdo em string. Vamos fazer também um writeFile, que também irá passar um file, e um contents, que vai retornar uma nova promise:

const writeFile = (file, contents) => {
  return new Promise((resolve, reject) => {
    fs.writeFile((file, contents), (err) => {
      if (err) {
        reject(err)
      } else {
        resolve()
      }
    })
  })
}

O nosso problema agora é que precisamos ler um arquivo e passar para o write, então precisamos fazer o seguinte:

readFile('promises.js').then((contents) => console.log(contents))

Ao mandar rodar o arquivo, perceba que ele retorna o nosso código em string, a vantagem disso é que agora conseguimos 'encavalar' uma promise depois da outra. A primeira alternativa que temos é utilizar o then dessa forma, então precisamos colocar o próprio writeFile:

readFile('promises.js').then((contents) => writeFile('tst.js', contents))

Essa é a primeira maneira que temos de encadear as promises. Ao rodar o arquivo, perceba que foi criado um tst.js como queríamos. A segunda forma é colocarmos encadeado realmente:

readFile('promises.js').then(writeFile('tst.js', contents))

Vamos dizer a ele para ler o nosso arquivo e em seguida escrever um outro arquivo, o problema é que se fizermos dessa forma, quando ele passar 'parseando' o código, ele já vai executar esse primeiro writeFile, se não estivéssemos passando um file, poderíamos fazer isso direto, mas como isso não acontece, temos que utilizar o bind, pois ele vai criar uma nova função, a onde eu posso passar o contexto que eu quero executar essa função e fazer um curring fixando alguns atributos da esquerda para a direita:

readFile('promises.js').then(writeFile.bind(null, 'tst2.js'))

A grande dica é entender como funciona isso. Podemos colocar um then após o outro, podemos fazer um novo teste:

const out (contents) => {
  return new Promise(resolve =>{
    setTimeout(() => {
      console.log(contents)

      resolve()
    }, 2000)
  })
}

Com isso, caso a gente queira fazer um teste no then, podemos fazer o seguinte:

readFile('promises.js')
  .then(out)
  .then(() => console.log('final'))

Retornando as promises nós conseguimos encadear, essa é uma grande vantagem em relação a um callback, afinal conseguimos fazer o código crescer para baixo ao invés de crescer para frente, evitamos o callback hell.

Confira o video:

Deixe suas dúvidas e sugestões nos comentários. Curta o DevPleno no Facebookinscreva-se no canal e não se esqueça de cadastrar seu e-mail para não perder as novidades.  Abraço!

Tulio Faria
Autor
Tulio Faria31 de agosto de 2017

Últimas do Blog