‫Instrutor: Neste vídeo, iremos promissionar as
‫funções de leitura de arquivo e gravação de arquivo.
‫O que significa que faremos com que eles
‫retornem promessas em vez
‫de passarmos funções de retorno de chamada para eles.
‫Então, se você quiser, é basicamente uma função de leitura de
‫arquivo que retorna uma promessa
‫e que recebe apenas o nome do arquivo, sem retorno de chamada.
‫Então, vamos fazer exatamente isso.
‫Então, vamos criar uma função pro ler arquivo.
‫Tão pró para promessa porque, novamente,
‫retorna uma promessa.
‫E então tudo o que fazemos é passar
‫o nome do arquivo e como estávamos dizendo, retornar uma promessa.
‫Portanto, retorne uma nova promessa.
‫Portanto, usamos o construtor de promessa
‫aqui, que foi introduzido na linguagem com ES6.
‫Portanto, antes do ES6, como o ES5,
‫ES4 e todas
‫as versões anteriores, não havia suporte para promessas em JavaScript.
‫Mas eles mudaram isso no
‫ES6 e tornaram a linguagem muito melhor nesse aspecto.
‫Portanto, em relação ao JavaScript assíncrono.
‫Agora, este construtor de promessa
‫aqui leva em uma função chamada executor,
‫que será chamada imediatamente quando a promessa for criada.
‫E esta função terá dois argumentos, então
‫resolva e rejeite.
‫Portanto, resolva e rejeite, mas
‫por enquanto não se preocupe com eles,
‫estaremos falando sobre eles em um minuto.
‫Por enquanto, vamos nos concentrar apenas nessa função do executor
‫em si, porque é aqui que realmente fazemos
‫todo esse trabalho assíncrono.
‫Neste caso, o arquivo lido funciona.
‫Então é aqui que vamos chamar o fs. readfile com
‫o nome do arquivo que foi
‫passado e a função de retorno de chamada usual, certo.
‫Portanto, o erro e os dados são exatamente
‫como antes.
‫Portanto, tenha em mente que
‫não estamos realmente mudando a função de leitura de
‫arquivo, estamos simplesmente criando uma nova
‫função que, nos bastidores, é claro, ainda executa a função
‫de leitura de arquivo embutida, mas retorna uma promessa
‫para que possamos usar a
‫promessa em seu
‫lugar da função de retorno de chamada.
‫OK.
‫Portanto, temos a função de leitura de
‫arquivo aqui que fará
‫seu trabalho e, quando estiver pronta, retornará com os dados.
‫E agora é aqui que
‫as funções de resolução e rejeição entram em jogo.
‫Como esses dois argumentos estão
‫disponíveis na função do executor, eles são funções.
‫Agora, chamar a função
‫de resolução basicamente marcará a promessa como bem-sucedida,
‫portanto,
‫cumprida e retornará o valor bem-sucedido da promessa.
‫Então, vamos realmente fazer isso.
‫Portanto, chamamos de resolução com dados.
‫Portanto, qualquer variável que passarmos para a função de
‫resolução é a que estará
‫disponível posteriormente como o argumento no método then, certo?
‫Então, esses dados aqui serão o
‫valor que essa promessa retorna para nós, ok.
‫Isso provavelmente parece um pouco confuso, certo?
‫Portanto, novamente, tudo o que passamos para essa função aqui, para
‫a função de
‫resolução, é o resultado da
‫promessa que estará disponível no manipulador then.
‫Por outro
‫lado, também podemos marcar a promessa como rejeitada
‫caso tenha ocorrido um erro.
‫E fazemos isso chamando,
‫como você
‫provavelmente pode imaginar, a função de rejeição.
‫Então, se houve um erro e
‫isso é parecido com o que fazíamos antes.
‫Portanto, se houver um
‫erro aqui, chame a função de rejeição.
‫E tudo o que passarmos para
‫este será o erro que
‫estará mais tarde disponível no método catch.
‫Então, neste aqui.
‫OK?
‫Então vamos apenas passar uma
‫string aqui, não consegui encontrar aquele arquivo, algum emoji aqui talvez
‫para fazê-lo aparecer um pouco mais em
‫nosso console. logs, certo?
‫E tudo bem.
‫Na verdade, já é isso.
‫Então, vamos revisar isso aqui novamente.
‫Então criamos um novo
‫arquivo, nele passaremos um nome de arquivo.
‫Portanto, este argumento.
‫E tudo o que fazemos aqui é retornar essa promessa.
‫Essa promessa tem uma função de executor, então
‫esta aqui,
‫que é onde fazemos nosso trabalho assíncrono.
‫Nesse caso, é claro que é o nosso
‫fs. readfile.
‫Então, se obtivermos nossos dados de maneira
‫bem-sucedida, chamaremos a
‫função resolver com o valor resolver.
‫E se houver
‫um erro, chamamos a função de rejeição, certo?
‫E agora vamos realmente usar isso na prática.
‫Leia o arquivo pro, nós passamos
‫nosso nome de arquivo.
‫Então é esse, é claro,
‫e é isso.
‫Portanto, agora será uma promessa.
‫E assim como
‫antes, podemos usar nosso método then nisso.
‫Ok, então este argumento de dados aqui será
‫exatamente o que retornamos da promessa, caso
‫tenha sido bem-sucedido.
‫Então, com essa resolução.
‫Portanto, agora nosso arquivo
‫de cachorro contém
‫labrador e esses dados aqui serão labrador.
‫E isso está disponível posteriormente em
‫nosso manipulador aqui.
‫Mas é claro que não precisa ter o mesmo
‫nome, eu também poderia chamar
‫de resultado ou algo não importa, certo?
‫Ok, agora vamos pegar tudo isso e
‫realmente colocá-lo aqui.
‫OK.
‫Livre-se de tudo isso, salve e
‫será executado.
‫Agora temos esse erro aqui, então
‫os dados não são definidos.
‫Isso é porque eu mudei aqui para um resultado.
‫Então, vamos voltar e mudar para dados porque aqui
‫temos dados e aqui
‫temos dados
‫e, dessa forma, não preciso ir em
‫frente e mudar todos os nomes de variáveis.
‫Salve novamente e aqui
‫vamos nós.
‫Então funcionou, entende?
‫Na verdade, pegamos a raça,
‫que ainda é
‫labrador e desta vez da nossa promessa, ok.
‫Então, isso realmente funcionou.
‫Portanto, nossa função pro ler
‫arquivo agora retorna
‫uma promessa e os dados aqui estão disponíveis em nosso manipulador de então.
‫Ótimo, então ele já está
‫funcionando e podemos torná-lo
‫muito melhor
‫e vamos fazer isso, mas por enquanto eu
‫também quero prometer essa função de escrever arquivo aqui.
‫Então, basicamente, faça o mesmo
‫que fizemos com a função de leitura de arquivo.
‫Agora, se você já conhece um pouco
‫sobre no js, talvez você esteja pensando que na verdade existe um
‫nó de função que irá promisificar funções automaticamente para nós.
‫Mas é claro que eu queria mostrar
‫aqui como as promessas realmente
‫funcionam e como
‫as construímos e é por isso que estou fazendo tudo isso aqui, ok.
‫Então, eu realmente quero que você aprenda sobre as promessas,
‫não apenas como nós as consumimos,
‫mas também como construí-las.
‫E é por isso que estou fazendo assim.
‫Então, escreva o arquivo e como uma promessa.
‫E este, na verdade, não precisa apenas do nome
‫do arquivo, mas também dos dados que devem ser gravados nesse arquivo.
‫Mas então a lógica aqui é bastante semelhante.
‫Então, novamente, retornamos uma nova promessa,
‫nela temos nossa função executora
‫que assume resolver e rejeitar como o argumento.
‫E esses são
‫nomes padrão, então resolva e
‫rejeite, você poderia chamá-los do que realmente
‫quisesse, mas esse é o tipo de padrão, certo.
‫Então fs,
‫escreva o
‫arquivo, passamos o arquivo, os
‫dados e então a função de retorno de chamada.
‫E agora algo muito semelhante a antes,
‫então se houve
‫um erro, chame a função de rejeição
‫e passe alguma mensagem lá.
‫Não foi possível gravar
‫o arquivo, novamente com esse emoji aqui para que ele se
‫destaque um pouco mais e caso tudo funcione
‫bem, então é só resolver.
‫Agora não temos nenhum dado realmente para passar aqui, certo?
‫Então, vamos apenas passar em alguma string
‫aleatória algo como dizer sucesso, ok.
‫Portanto, uma promessa
‫nem sempre precisa retornar um valor significativo.
‫Nesse caso, tudo o que realmente estamos
‫tentando fazer
‫aqui é escrever um arquivo que não retorne um valor significativo.
‫Agora estamos prontos para usar essa função prometida, mas antes
‫de
‫fazermos isso, vamos implementar o encadeamento
‫sobre o qual falei antes.
‫Então, no
‫momento, ainda temos retornos de chamada dentro de retornos de
‫chamada dentro de retornos de chamada, certo?
‫Temos isso então, que
‫tem esse retorno de chamada.
‫E então, há outro manipulador then que
‫tem ainda outro callback nele.
‫Então isso realmente não muda nada, muda?
‫Em vez disso, queremos encadear esses manipuladores aqui.
‫E o segredo para
‫fazer isso é fazer com que cada manipulador retorne uma nova promessa.
‫Então, como vamos fazer isso?
‫Bem, lembre-se de que esta função aqui retorna uma promessa.
‫E então tudo o
‫que temos a fazer é retornar a promessa deste primeiro manipulador.
‫Deixe-me mostrar isso para você.
‫Então, dizemos superagente de retorno. pegue e então
‫a string e isso agora é uma promessa, ok.
‫E então fechamos essa função de retorno
‫de chamada aqui e encadeamos esse método então diretamente nele.
‫Salve, agora temos algum erro aqui e
‫isso está na linha 40.
‫Vamos nos livrar disso aqui e
‫tudo bem.
‫Ele mudou a formatação aqui para
‫nós de novo
‫que era mais bonita e então já a temos funcionando aqui.
‫Então, por que isso funciona de novo?
‫Bem, é claro que essa função que
‫criamos no início retorna uma promessa.
‫Assim, podemos usar o método then.
‫Em seguida, fazemos com que essa função de retorno de
‫chamada que está nela retorne uma promessa.
‫E assim
‫podemos encadear o próximo manipulador.
‫Portanto, esta variável
‫de resultado aqui será o valor resolvido
‫desta promessa que retornou do manipulador anterior, certo?
‫Faz sentido?
‫Agora, para dar um passo adiante,
‫iremos em
‫frente e usaremos nossa função write file pro aqui agora também.
‫E uma vez que queremos continuar encadeando os
‫métodos then, retornaremos isso na verdade.
‫Então volta, escreve o arquivo pro passa o nome
‫do arquivo, que é esse aqui, os
‫dados ...
‫E é isso mesmo.
‫Ok, então não precisamos mais de nada disso aqui, vamos
‫apenas comentar por enquanto.
‫Livre-se deste espaço
‫aqui e ali podemos encadear o próximo manipulador.
‫Então, e lembre-se de
‫que aqui não tínhamos nenhum valor resolvido significativo.
‫Portanto, não queremos nenhum argumento
‫para esta função de retorno de
‫chamada aqui, tudo o que queremos fazer é registrar essa string, certo?
‫Então agora podemos realmente nos livrar disso
‫e tudo bem.
‫Então, aqui embaixo, vemos
‫agora que já está funcionando.
‫E, novamente, o truque para
‫ser capaz de encadear todos esses métodos então
‫é retornar uma promessa antes de chamar cada um deles.
‫Portanto, este aqui obviamente retorna uma promessa aqui,
‫então podemos encadear o método then nele.
‫Então, este pedaço de
‫código aqui retornará
‫uma promessa e, portanto, podemos usá-la nela.
‫Então esse trecho de
‫código retornará uma promessa e então podemos usá-lo novamente, ok?
‫Então esse é o segredo.
‫Tente salvar novamente
‫e aqui embaixo veremos que a raça ainda é labrador.
‫Vemos que este aqui é o link, vamos aqui
‫e confirmamos que este aqui é
‫mesmo o mesmo que este.
‫E então ele gravou com sucesso a string no arquivo de
‫texto usando nossa função de gravação de arquivo prometida, certo.
‫E então, no final, temos esse gerenciador de erros.
‫E a beleza aqui é que, para todas essas cadeias e,
‫em seguida, manipuladores
‫no final, precisamos simplesmente de um único manipulador de captura.
‫Portanto, uma função que lida
‫com os erros provenientes de qualquer uma das três promessas, certo.
‫Na verdade, vamos apenas registrar o erro no
‫console e tentar, por
‫exemplo, alterar este arquivo aqui.
‫Na verdade não é
‫o arquivo, mas vou mudar o nome do arquivo
‫aqui, salve-o e agora vemos que não consegui encontrar esse arquivo.
‫Então de onde vem isso?
‫Isso vem direto
‫da chamada da função de rejeição, certo?
‫Portanto, temos um erro aqui porque não conseguimos encontrar o arquivo
‫e, por isso, chamamos a função de rejeição.
‫E essa função de rejeição marcará esta promessa aqui, então lembre-se de
‫que esta é uma promessa.
‫Irá marcá-lo como rejeitado.
‫E, portanto, a função catch é chamada.
‫E então registramos esse erro no console.
‫E o resultado disso é o que você pode ver aqui.
‫Ok, vamos colocá-lo de volta agora que
‫funciona.
‫Agora vamos entrar no arquivo, criar
‫um cão que não existe
‫e agora, oh, aqui temos esse grande erro estranho e isso é porque
‫estamos simplesmente registrando todo o erro e não a
‫mensagem de erro como estávamos fazendo antes, mas não
‫não importa.
‫Agora salve aqui agora, coloque
‫de volta
‫e tudo bem.
‫Então agora está tudo funcionando
‫e nos livramos daquela forma triangular que
‫tínhamos em nosso
‫código e agora temos uma chamada estrutura plana de promessas em cadeia.
‫Então, novamente, esta é a maneira
‫mais fácil de gerenciar e espero que você possa
‫começar a apreciar isso e também é mais
‫lógico pensar e raciocinar sobre o código como este.
‫Agora, na
‫próxima aula, iremos realmente dar um passo
‫adiante e tornar isso ainda mais
‫legível e fácil de usar.
‫Portanto, fique atento para isso.