>> Tudo bem.
Assim, o suspense foi, o que é Node.js como você sabe que hoje em dia?
Alguma coisa? Sim?
>> Era como um quadro de escrever JavaScript
aplicações amplamente -
>> OK, isso funciona.
>> - Eu sei como usos comuns, como -
ou algo que você pode fazer é como -
[Inaudível Observação]
OK >> bom.
Sim, por isso é um quadro.
É um motor pelo qual você pode executar código JavaScript
site do servidor.
Isto pode significar o mais simples das coisas
como escrever uma linha de comando script não em Python ou Bash
ou Ruby ou PHP, mas apenas em si JavaScript
e executá-lo em um piscar prompt de comando.
Ou você pode realmente executar lo dentro de um servidor web.
E, de fato dentro node.js si,
este quadro é um grupo inteiro bibliotecas de entre os quais
no servidor HTTP embutido.
Assim, você pode realmente escrever um servidor, como veremos
em apenas um momento, super fácil apenas para entender um pouco
de HTTP e TCP e portos.
E você pode gerar uma escuta servidor web Apache, sem,
sem IIS da Microsoft.
Sem qualquer outro software instalado,
você pode apenas gerar este e ouvir mais qualquer porta
em que o sistema você está autorizado a.
Assim, caso e pontos, deixe-me ir e abrir
esse exemplo, o servidor-0.js.
Então, observe que a parte superior este arquivo, apenas um bando
dos comentários desinteressantes, e, em seguida, há um par
de linhas representativas de código que vamos ver recorrentemente.
Então, var HTTP recebe exigir "HTTP".
Então, built-in para node.js ' infra-estrutura é um grupo inteiro
de módulos que são realmente apenas bibliotecas e tudo é uma espécie
de espaço de nome com o identificador exclusivo
como este é "HTTP".
De modo que, como em muitos linguagens como Java e C + +
e C, somente quando você importar ou incluir
ou no nó falar requerem um módulo faz seus bits.
E toda a memória requer obter carregado
na memória RAM e, por conseguinte, utilizada.
Assim, você espécie de carregar este bibliotecas ou módulos sob demanda.
Isso significa ir em frente e requerem
para este programa a biblioteca de HTTP,
e referem-se a essa biblioteca por forma de uma variável chamada HTTP.
Mas este símbolo da esquerda poderia ter sido chamado de qualquer coisa, foo,
bar, baz, não importa.
Assim, ao contrário do C + + e Java e C, onde quando você precisar
ou importar uma biblioteca, que apenas uma espécie
de torna-se globalmente acessível,
Node.js módulos são mais firmemente namespace.
Assim que a própria - que a funcionalidade só é acessível no momento
por meio desse nome variável.
Você não pode simplesmente começar métodos de tipagem que existem
em que o direito de uma maneira o que provavelmente é bom,
porque então o seu namespace não fica tão confuso
como em muitas línguas.
Tudo bem, então agora como o comum sugerem, a criação de um servidor HTTP
como Jonathan [assumido ortografia] era possível é, literalmente,
tão simples como chamar o criar método do servidor dentro
do módulo HTTP.
Então, isso está voltando a referência
a algum tipo de servidor web.
Ele veio para o Apache, não peso necessariamente tão pesado.
Essa é um pouco mais simples.
E agora, eu tenho que apenas simplesmente fazer algumas coisas.
Então, primeiro, deixe-me rolar até o fundo aqui
e pular o manipulador método por um momento.
E observe esta linha de código,
server.on que é essencialmente significa servidor -
ouvir como no código jQuery,
ouvir para um evento chamado pedido
e apenas dar um palpite o que devo fazer
quando um evento de pedido incêndios no servidor.
Sim?
>> Ligue o manipulador função.
Assim, literalmente executar o código que é referenciado
por esta variável e, na verdade, não uma variável para símbolo aqui,
o que é que o símbolo referindo?
Bem, este nome funcionar aqui
e manipulador, aparentemente, leva dois argumentos.
Por que dois? Bem, se você acabou de leia a nenhuma documentação
para este módulo específico, você será informado de que o manipulador
que será chamada será passaram pelo menos dois argumentos,
uma referência ao pedido,
e dentro do que pedido literalmente significa solicitação HTTP.
Assim, todos os cabeçalhos HTTP que você pode se lembrar
desde o início da semestre ou alguma classe anterior
ou experiência como o obter linha ea linha de acolhimento
e linha User-Agent, tudo isso é encapsulado e mais dentro
deste objeto pedido.
E o objeto de resposta é classificadas para os dados de saída.
Assim, você tem uma referência a um objeto que está indo para permitir que você
para enviar informações de volta para o navegador chamando métodos
em que este último argumento Res chamado para uma resposta.
Mas isso poderia ser chamado foo ou bar, este são apenas convenções.
Então, agora, o que eu faço?
Bem, parece que dentro deste servidor web super simples
que eu estou implementando, eu sou vamos fazer o seguinte.
Eu vou escrever um HTTP header com código de status 200,
200 significado bem, tudo está bem.
E então, eu vou repassar aparentemente.
Qual é o tipo de dados segundo argumento para a cabeça né?
>> É um objeto?
>> É um objeto com quantas chaves e valores?
Apenas um de cada um, direito, um valor de chave do par.
Assim, "tipo de conteúdo".
E a única razão Estou citando isso aqui é
porque o hífen pode ser confundida por um sinal de menos
ou algo parecido.
Então, eu tenho que citá-lo aqui, singe ou aspas duplas.
Mas novamente paradigma comum
em código JavaScript é muitas vezes aspas simples nos dias de hoje,
cólon e, em seguida, o valor.
Então, este é apenas o o chamado tipo mente.
Este é um cabeçalho HTTP que vai literalmente
de se contentar tipo hífen cólon barra de texto simples que está acontecendo
a ser enviado a partir do servidor para o navegador
de modo que o navegador sabe se deseja executar este texto como Raw
, HTML ou como um imagem ou um filme
ou um arquivo flash ou qualquer outra coisa.
Agora, onde eu realmente quero para enviar no corpo da página?
Bem, só por leitura documentação
para o objeto de resposta dentro desta biblioteca.
Vejo que há um certo método e que recebe uma string,
talvez outras coisas, mas minimamente uma string.
E a cadeia é o que é cuspir para o navegador.
Neste caso, sua super simples, o seu Olá mundo,
mas poderia ser opne suporte, html, próximo suporte,
cabeça suporte de abrir, fechar suporte e assim por diante,
este poderia ser html Raw.
Mas estamos mantendo o exemplo simples por apenas cuspindo
o mais simples dos tipos de mente que é sem dúvida text / plain.
E então apenas Response.End significa fechar a conexão
e enviar tudo o que tenho espécie de tampão dentro
deste objeto de volta para o navegador.
Eu sou feito. Tudo bem.
Assim, a última coisa Eu estou fazendo aqui em baixo
e isso é um tanto arbitrário e destinadas a ser legal,
é que eu estou dizendo a servidor finalmente ouvir
em um determinado TCP pela porta padrão.
Lembre-se de início de classe que os serviços -
ou você tipicamente exclusivamente identificá-lo por números
AD é a web, 443 é baseado em HTTP sites, 22 é o SSH, FTP é 21
e 1337 é apenas arbitrária mas é maior que 1024
o que significa que na maioria sistemas, eu posso usá-lo
sem a necessidade de super privilégios de usuário.
Então é só conveniente.
Mas 8080 é em off - uma comum um, 8088, qualquer coisa realmente grande
aos milhares como comum Mas este é apenas mais elite.
Tudo bem, então o que acontece quando eu realmente executar este?
Bem, eu não basta visitar a página em um navegador.
Este arquivo é chamado de servidor 0.js.
Porque mais uma vez, o Apache é agora fora do quadro
para o segundo semestre do curso.
Se eu quiser web servidor, eu preciso escrever
e depois executar este servidor web.
Mas acontece que o JavaScript tanto no lado do cliente
e o lado do servidor é uma linguagem interpretada.
Então, tudo que eu preciso é um intérprete.
Assim é - se insistir para executar nó e, em seguida, server-0.js,
I pode ou não ver alguma saída dependendo
sobre o que as bibliotecas eu incluí, nada parece estar acontecendo.
Mas deixe-me ir a um navegador e deixe-me ir
para o mesmo endereço IP dos meus clientes CS50.
Mas isso poderia apenas bem ser o meu Mac
ou o meu PC e, em seguida, pressione enter.
Isso realmente parece Apache.
Isso é como o diretório listando olhamos
em no primeiro semestre.
Então, o que eu fiz de errado?
É.
[Inaudível Observação]
Exatamente, não é?
Assim, o Apache ainda está escutando na porta padrão 80.
Mesmo que eu poderia mudar isso, Eu poderia desligá-lo todos juntos
mas ele ainda está em execução.
Mas esses caras podem certamente coexistir.
Eu simplesmente tenho que colocar cólon 1337 e então talvez
ou talvez não uma barra de o fim para acessar esta porta
que este servidor está sendo executado.
E agora eu vejo que Olá, mundo está de volta.
E eu posso bater de recarga como quantas vezes eu quiser,
ele ainda está servindo uma página.
Na verdade, se eu abrir Chrome inspector, ir para rede
e, em seguida, recarregar a página inteira,
perceber que, na verdade isso foi o pedido que foi enviado.
Se eu olhar para a fonte de Raw,
notar meu navegador envia todas essas coisas.
E, em seguida, a resposta de o servidor foi super simples.
Existe a 200.
Se não for muito baixa na tela,
há o tipo de conteúdo.
E então node.js tipo de automaticamente
para me adicionou a data e todas as outras coisas
que os navegadores normalmente esperar.
Então, vamos ver um pouco verificação de sanidade.
Deixe-me voltar para o código em server-0.js e deixe-me -
toda vez que eu entrar em manipulador,
deixe-me dizer console.log.
("Nós tivemos um visitante! ').
Eu não preciso recompilar ou qualquer coisa assim,
é uma linguagem interpretada.
Então, agora, deixe-me voltar para a página, recarregar um, dois,
três vezes e ir Voltar para a minha janela.
E agora eu vejo isso.
Bem, isso é estranho, Vejo seis linhas.
Interessante web trivia, por que Recebo seis pedido não três?
Sim?
[Inaudível Observação]
É. Então, como você pode saber o pequeno ícone estúpido no topo
da barra do navegador que muitas
de sites de poder usado ser uma crista de Harvard,
pode ser um logotipo da empresa ou qualquer coisa assim.
Assim, os navegadores estes dias espécie
presunçosamente de fazer uma solicitação HTTP adicional
para quase todos os site que você visita verificando se existe
por padrão um arquivo chamado favicon.ico
no mesmo diretório o arquivo que você solicitou.
E se assim for, ele coloca o ícone lá.
Então, todos nós estamos vendo é exatamente isso.
E, de fato, vamos ver se nós pode ver isso em vez de Tipo
fora apenas, "Nós tivemos um visitante '.
Deixe-me ir em frente e saída.
E eu só sei que isto olhando a documentação.
Há uma propriedade no interior de o objeto do pedido chamada URL
que passa a ser o caminho
que foi solicitado na URL real.
Então, se eu reiniciar o servidor simplesmente executando novamente nó
no servidor e 0.js agora que este um, dois,
três e voltar aqui.
Aqui está.
Slash é o que eu - o humano solicitado
em favicon.ico é o que o navegador é
presunçosamente requerente.
Mas o ponto não é tanta coisa favicon
mas como o servidor é operado.
Sim?
>> Por que é que isso tem ser algum pedido?
>> Por que isso tem que - por natureza, de como funciona HTTP.
Então, HTTP só pode solicitar um arquivo de cada vez.
Os navegadores podem ser inteligente nos dias de hoje
e manter o TCP conexão aberta.
Se você tomou CS143 ou geralmente familiarizado com a rede,
para que possa obter ganhos de eficiência
, mantendo a rede soquete aberto
em fazer HTTP múltipla pedidos serialmente sobre ele
mas eles são um arquivo por solicitação.
Então, se você visitar algo como -
Quero dizer que pode ir para a maioria qualquer site.
Se você vai para - vamos puxar para cima inspetor do Chrome aqui.
Pode obter mais preencher da página.
Vá para a aba de rede e ir para www.cnn.com.
E quando você visita cnn.com, a sua homepage -
seu navegador, em vez atrozmente faz - ainda contando.
OK. Pelo menos 289 HTTP solicitações de novo e de novo.
E é por isso que quando você visita sites particularmente inchado,
eles são lentos para carregar por causa de tudo
dos ativos que eles estão carregando.
Então, parece que 298.
Pode haver alguma Ajax acontecendo neste momento ou algum
dos ativos são apenas baixa.
Assim, cada um deles é um pedido individual de voltar
e para frente, para trás e para frente.
E é por isso mais cedo, mesmo embora nós meio que falou
sobre ele um pouco fantasiosa onde você colocar a tag script,
absolutamente faz uma diferença quando você tem -
ele começa a ter um monte de tráfego e um monte
arquivos de ser solicitado.
E cada um que representa provavelmente uma imagem, um arquivo de mídia,
um arquivo JavaScript, Arquivo CSS ou algo semelhante.
Então, já estamos até cerca de 4 megabytes apenas
olhar para as notícias de hoje.
Boa pergunta.
Tudo bem.
Então, quais são alguns dos os prós embora?
Certo, nós sabemos como fazer webpages já com PHP.
E muitos de vocês vieram para a classe sabendo Django
e Python ou trilhos com Ruby.
Então, por que precisamos de mais um linguagem e infra-estrutura?
O que é particularmente node.js bom em se você sabe?
[Pausa]
Alguma coisa?
Não? Sim?
Afinação >> mensagens.
>> Então, transmitindo mensagens.
Então, isso é verdade e é verdade por uma razão mais técnica
e que node.js e realmente JavaScript é particularmente
bem adequada para assíncrono código,
se em que você criar a ilusão
de fazer múltipla coisas ao mesmo tempo.
Assim, mesmo que eles estão realmente está acontecendo em série,
de facto, na maioria dos casos, JavaScript lado tanto o cliente
e do lado do servidor é rosca única.
Que se você está tomando 161 ou mesmo 61 significa que -
deste programa sabe,
o intérprete pode literalmente apenas fazer uma coisa de uma vez.
Mas isso é não é grande para algo como um servidor web
onde você pode ter dezenas ou centenas ou talvez até milhares
de todos os usuários que tentam para acessar a sua página web
ao mesmo tempo.
E, no entanto, que sugerem que lidar com eles um
após o outro, após o outros, especialmente se alguns
daqueles pedido como vimos na CNN pode exigir servindo
até 300 arquivos antes de você até chegar ao próximo usuário
quem quer ver o diz notícia.
Node.js é mais adequado para ambientes como esse.
Porque o que acontece é qualquer processo de execução lenta
como ler um arquivo do disco ou consultar um banco de dados ou falar
a algum outro servidor de rede,
que tende a ter latência, certo?
Se demorou 61 ou 161 especialmente tudo desse tipo
de serviços periféricos tendem a ser muito mais lento
do que não fazer nada dentro de a mesma memória RAM e o mesmo CPU
que dizer, neste caso, o servidor está realmente funcionando.
Mas o que é agradável sobre Node.js é que você pode -
e JavaScript de forma mais geral é que você pode fazer algo
e, em seguida, dizer: "Hmm, isso vai
para me levar alguns milissegundos ou até mesmo alguns segundos.
Deixe-me uma espécie de garfo que fora ", mas não é um processo de verdade.
E então, quando ele é feito fazendo processo em execução que lento
como pegar linhas de uma banco de dados ou a leitura de um arquivo. html
do disco, ele vai voltar para mim, em vez
do que eu ter que esperar por ele.
Assim, para tornar isso mais claro.
Este é o meu meio de tornando este mais familiar.
Tudo bem, então este é o Shake Shack na praça.
Esta é uma espécie de paradigma comum
para explicar asynchronicity.
Este é realmente um bom exemplo, porque Shake Shack
e Burger Tasty são notavelmente lento para o que eles fazem.
Mas o ponto é que eles são realmente bom em receber ordens
e tendo o seu dinheiro depois que você espera para o seu alimento.
Então, essa é realmente uma melhor design do que a alternativa.
Porque acho que você anda em uma loja como esta e você tem
para a frente da linha e fez o pedido e você quer
de hambúrguer, o melhor que posso dizer, é preciso pelo menos cinco
ou mais minutos para realmente obter um hambúrguer.
Assim, seria tipo de um modelo de negócio ruim
se enquanto você está esperando para o seu hambúrguer, Alice [ortografia assumido]
e Bob [assumido ortografia] e Charlie [ortografia assumido]
e todo mundo está fila atrás de você
e você está literalmente bloqueando a fila de espera para o seu alimento.
Então, obviamente, no Shake Shack
e outros fast food lugares não fazer isso,
eles fazem algo assim.
Eles dão-lhe uma campainha.
E eles tipo de enviá-lo em seu caminho.
E eles chamam você de volta por fazer esta pequena coisa vibrar
ou flash para chamar sua atenção.
Então, isso é literalmente o que?
Algo como node.js faz.
Se Node.js ou JavaScript mais geralmente está sendo usado
e o programador é inteligente o suficiente
a perceber, "Quer saber?
Tudo o que eu preciso fazer direito aqui pode levar algum número
de milissegundos ou segundos.
Você sabe o que?
Deixe-me ir em frente e não chamá-lo de forma síncrona -
"Que é cara de bloqueio todos os outros na linha ", -
deixe-me ir em frente e tipo de afastar
e simplesmente me chamar de volta
quando essa longa duração operação está concluída. "
E chamar de volta é claro alude, neste caso,
para uma função de retorno de chamada, um referência a um mandril de código
que serão executados quando o seu hambúrguer está pronto,
muito parecido com essa coisa de ter alguma tipo de funcionalidade built-in
que ele começa a vibrar ou zumbido quando está na hora de você
a ser chamado de volta para a frente da fila.
Então, o que isso significa, em termos reais?
Bem, nós temos que trabalhar o nosso caminho para cima.
Então, deixe-me ir em frente e fazer isso em primeiro lugar.
No server-1.js, deixe-me primeiro simplificar o código
para que possamos dar passos de bebê na direção um problema mais convincente.
Este é exatamente o mesmo programa que eu escrevi antes.
Mas o que foi alterado?
Há uma espécie de uma ligeira diferença sintática
entre esta e versão 0 há pouco.
O que salta à vista você se lembra?
Sim Cynthia [assumido ortografia]?
[Inaudível Observação]
É. Então, agora, temos uma linha de da função que está sendo passada dentro
Já se livrado do tipo
de inutilmente chamado função de manipulador.
Useless apenas em que, antes de mesmo chamando-o em um lugar,
Eu realmente não precisa perder tempo dando-lhe um nome
e tornando mais difícil ler o código de topo para baixo.
Então, vamos declarar em linha é uma função anônima.
E eu estou fazendo duas outras coisas.
Eu estou fazendo melhor uso de notação de ponto.
Assim como em jQuery, um monte de nó métodos podem ser encadeados.
Assim que uma vez que você é feito chamando alguma coisa, você não tem
esperar para uma nova linha e chamar outro método,
você pode apenas cadeia los juntos.
E assim, desta forma, podemos realmente apertar isso.
Então, isso é, literalmente, um servidor web em cinco linhas
de código contrário do total de -
ao contrário do que você normalmente tem que fazer para definir alguma coisa.
Se eu entro em servidor 2 Agora, vamos fazer isso.
No servidor 2 - na verdade, vamos voltar para o servidor 2.
Vamos agora abrir async-0.js e resolver esse problema em mãos.
Então, primeiro, vamos em frente e aberto
se assíncronos-0.js no navegador.
Então async-0, deixe-me ir volta para o navegador.
Hit reload.
E agora, este é o tipo de mensagem de erro.
Na verdade, eu estou vendo um 500 no inspetor do Chrome.
Mas deixe-me mais precisamente solicitar hello.txt.
OK. Então, isso parece funcionar.
Então async-0.js não parece servir-se algo para barra.
Não tem suporte a arquivos padrão.
Mas se eu explicitamente solicitar hello.txt,
que parece estar apoiando.
Por que isso?
Bem, o que eu já passei aqui
e feito é implementado um servidor web super simples
que demonstra que assincronia pode ser útil.
E isso é implementado como se segue.
Primeiro, eu estou usando o Módulo HTTP novamente
mas também que a FS provavelmente significa?
Em geral no CS, sistema de arquivos.
Sistema de arquivos OK.
Daí por diante FS, sistema de arquivos.
Tudo bem, então o que isso me dá?
Funcionalidade relacionada com arquivos como se passou,
abrir arquivos, escrevendo diretórios, leitura diretórios
e todas essas coisas.
Então agora perceber, este código é a mesma que antes,
criar o servidor, passando em uma função anônima.
Este é o tipo de arbitrariedade.
Isto não é muito servidor web seguro.
Na verdade, você pode acessar mais qualquer arquivo no meu disco rígido
ou no servidor do disco conduzir executando este código
porque eu sou apenas cega supondo que eu vou
para agarrar o que o utilizador solicitado na URL.
E eu vou prefixo com dot
de modo que eu sou marginal sendo seguro
dizendo qualquer arquivo que podem pedido tem que, pelo menos de início
no diretório atual.
É claro que há uma ameaça aqui.
Porque se eles ao invés de incluir o que?
Em seu caminho, eles podem tipo de contornar isso também.
Ponto, ponto, certo?
Assim, se o usuário apenas colocar ponto, ponto no URL, em teoria,
eles poderiam começar a receber meu - e dizer arquivo de senha.
Assim, este não é destinado a ser protegido,
que está destinado a ser simples.
Então, aqui, eu tenho uma variável que é a concatenação de ponto
que está presente diretório ea URL de solicitação
que vimos antes é como cortar ou / hello.txt.
Então, agora, torna-se um pouco mais interessante.
Primeiro, observe o fundo.
Estou ouvindo no mesma porta que antes.
Portanto, a verdadeira interessante trabalho é aqui dentro.
Cada vez que um pedido vem por natureza
deste código, o que estou fazendo?
Eu estou chamando arquivo método de leitura de arquivos do sistema,
passando o caminho que eu quero ler.
E agora, este é o que é interessante aqui,
isto é, de implementação no método assíncrono.
Você não pode obter um retorno valor a partir do arquivo de leitura.
No aviso de fato, não há expressão do lado esquerdo não
à esquerda do arquivo de leitura.
Ela não retorna um valor.
Em vez disso, ele chama um callback funcionar quando estiver pronto
para dar-lhe de volta uma resposta.
Então mais uma vez para ficar claro, enquanto que em outros tempos,
em muitos programação línguas, se você quiser
para ler um arquivo de caso no ponto PHP,
arquivo sublinhado obter ressaltam conteúdo,
você tem uma expressão à esquerda em todo o valor depois -
antes do sinal de igual, isso significa que você está atribuindo
para essa variável o retorno valor desta função.
Você pode fazer isso em Node.js, mas você normalmente tem
chamar explicitamente síncrona versões de funções como,
Eu acho que ele é lido sync file sync ou ler o arquivo.
Eu esqueci como ela foi batizada como.
E isso daria você um valor de retorno.
Mas se esse arquivo estiver em algum sistema de arquivos remoto
ou o disco é apenas naturalmente lento, isto pode levar 10 milissegundos
ou 2 segundos para o arquivo para realmente voltar.
Entretanto, nenhum outro web visitantes estão sendo atendidos
pelo seu websit.
Você está bloqueando.
Isso é o que é chamado bloquear IO, entrada / saída.
Então, aqui, isso é muito mais inteligente.
Porque o que está acontecendo node.js
fazer sobre a interpretação é o seguinte,
que vai chamar o método de arquivo de leitura,
tentar um backup do arquivo que tem um caminho especificado pelo valor P.
E então, se e quando estiver pronto para dar-lhe de volta o conteúdo
do arquivo de P, ele chamará uma função cuja assinatura é
por convenção o seguinte.
Dois argumentos, o primeiro dos que é talvez um objeto de erro,
E maiúsculo, é um objeto chamado erro ou nulo
se não há tal erro.
E o segundo argumento - tomar um palpite - vai ser o quê?
Chama-se, obviamente, mas os dados o que é mais concretamente dados?
Índice >>?
>> O conteúdo ola.txt no exemplo Puxei
no meu navegador um momento atrás.
Portanto, em outras palavras para ler o arquivo e muitos node.js funções
como a não retornam valores.
Chamam callbacks e passar
a esses retornos de chamada que seria têm sido, tradicionalmente, o
valor de retorno.
A vantagem dessa abordagem é
que se pode chamar ler o arquivo de um T0.
O poder função de callback não ser chamado de um carrapato mais tarde
por assim dizer em T, que pode ser chamado de T1000,
mil carraças mais tarde.
Mas o ponto é que a resto do código neste arquivo,
se for o caso seria imediatamente ser executado enquanto node.js
e enquanto o sistema de arquivos descobre como ler
que arquivo e obter de volta para você.
Assim você cria isso -
de forma eficaz a ilusão
de paralelismo, deixando processos em execução mais lenta não é
bloquear as coisas importantes, a parte que a manutenção usuários.
Então, como é que vamos lidar com isso?
Isto é muito comum paradigma node.js.
E não há maneira apenas para simplificar isso é que vamos ver antes junto.
A primeira vez que se verificou Erro não é nulo.
Então, se não é falsa em seguida, houve um erro.
Eu não sei o que é, talvez o arquivo não existe.
Eu não tinha permissões.
O caminho está errado.
Qualquer número de coisas poderia dar errado.
Por enquanto, eu vou arbitrariamente regresso a 500
o que é erro interno do servidor.
Algo deu errado.
Eu realmente não me importo para o seu diagnóstico.
Então, vamos apenas dizer o usuário que está quebrado.
E então, eu vou fazer res.end,
e esta é a notação abreviada.
Lembre-se que o último vez que fiz res.write
e então eu fiz res.end.
Se você só quer enviar uma linha de saída,
você pode apenas fazer tudo de uma vez com res.end com um argumento,
e que vai enviar qualquer que seja a mensagem de erro é
dentro deste objeto para o navegador.
Foi bastante arqueando recordar um momento atrás.
Eu não tenho idéia o que isso significava à primeira vista.
Mas, quando eu pedi uma arquivo que não existia -
oops, precisamos correr o servidor novamente.
Quando eu solicitei um arquivo que não existia, EISDIR,
então alguma coisa sobre sendo diretório,
se eu fizer alguma aleatória corda lá,
aparentemente isso significa que o arquivo não existe mesmo.
E isso porque o meu código está simplesmente dizendo para escrever
o que quer que o Raw Mensagem de erro é,
por isso não muito amigável mas pelo menos eu estou lidando com isso.
Outra coisa, se não fosse um erro o que eu estou fazendo?
É a mesma coisa de antes espeto um 200 OK, uma planície -
texto / tipo e mente simples depois cuspir os dados.
E é por isso que eu estou recebendo o conteúdo de hello.txt que apenas
para confirmar se eu olhasse em hello.txt,
é literalmente apenas Olá, mundo.
E se eu mudasse este Olá, mundo, salvar o arquivo,
execute novamente o servidor, recarregar a página.
Agora, eu recebo essa versão.
Então, eu realmente só reimplemented um servidor web
como está existe há muitos anos, mas usando Node.js.
Mas podemos fazer isso ainda mais limpa.
Deixe-me abrir async-1.js.
Agora, repare que eu estou adicionando outro módulo este tempo,
aparentemente, o módulo de caminho.
Agora, esta é uma boa oportunidade de olhar
em que a documentação parece.
Node.js é documentação.
Como PHP eu acho que é realmente muito bom
e para a frente.
Se eu for para node.js e Google e procurar caminho Node.js,
o que você vai ver normalmente é um link direto para uma URL
que eu coloquei aqui um momento atrás.
Então / api é o local oficial para ir para a documentação.
E o que você vai ver no topo
de documentação oficial do nó é de todos os métodos e
ou propriedades dentro de Neste módulo particular,
um dos quais é chamado de junção.
E junte-se é a função de auxiliar que vai me permitir
para não se preocupar com todas as vantagens.
E tem o agregado bônus, como você verá
das docas é também normaliza o caminho resultante.
Assim, se o usuário ou você tem pontos ou dots ou qualquer combinação
desses tipos de relação caminhos, entre os prós
do método é que se juntou ele vai limpar tudo o que se
e dar-lhe uma canônico caminho sem qualquer
desses pontos ou ponto pontos.
Então, é uma coisa boa em geral para a segurança, pelo menos
Se você está verificando a valor retorno que eu não sou
neste caso simples em particular.
Mas eu queria usá-lo.
Então, eu agora criar o caminho a pouco mais de programação
com path.join vez concatenação de Raw.
Então, isso é um pouco mais limpo do que antes.
E agora notar que eu estou sendo um pouco mais inteligente, em vez
que apenas cegamente tente ler o arquivo,
Vou realmente chamar fs.stat.
Então, se você está familiarizado
com baixo nível C funções e C, mesmo PHP.
Muitas bibliotecas têm esta função de stat retornos
essencialmente estatísticas em um arquivo, o tamanho do arquivo,
as permissões, o nome e coisas assim,
e também implicitamente se o arquivo existe ou não,
e se é um arquivo ou diretório
ou link simbólico ou outra coisa.
Então agora perceber, eu sou chamando fs.stat.
E então, aparentemente, de acordo com a documentação,
Eu tenho que voltar em objeto de erro
ou nulo seguido por um objeto de estatísticas.
Mas vamos verificar isso, node.js.fs.
Aqui está o arquivo documentação do sistema.
Deixe-me olhar para as estatísticas.
Há muito mais de funções aqui.
Opa, que sincronia estatísticas, fs.stat.
Então, aqui, é assíncrona Estatísticas (2).
Isso significa que se você lembre-se das páginas principais,
o capítulo 2 da página principal,
isso significa que esta é, literalmente, apenas uma implementação de nó
do baixo nível função do sistema de estatísticas.
Assim, o retorno fica dois argumentos, erro e status
onde status é um fs.stats objeto.
Então, vamos ver o que este objeto é suposto a aparência.
Vamos clicar no hiperlink e eu vejo isso.
O objeto contém estatísticas aparentemente algum método auxiliar,
é arquivo, é o diretório, é um monte de outras coisas.
É o "é" arquivo que eu me importo cerca de, neste caso particular.
Então, aqui vou eu.
Se houve um erro, então deixe-me socorrer dessa vez
e assumir.
Se houver um erro, foi provavelmente um arquivo 404 não foi encontrado.
Poderia ser outra coisa
mas eu estou sendo um pouco preguiçoso aqui apenas para se concentrar
sobre os detalhes mais interessantes.
Mas para o usuário do propósitos, arquivo não for encontrado,
se houve algum erro informando o arquivo.
Caso contrário, deixe-me ver se o arquivo é na verdade um arquivo real.
Então, se não é um arquivo, ele existe.
Há algo lá, mas provavelmente é um diretório
ou talvez um link simbólico
ou qualquer outra coisa que é funky no sistema de arquivos.
De qualquer forma, o usuário não deve vê-lo.
Então, agora, eu só vou cuspir
convencionalmente não autorizado 403.
Mas, novamente, apenas uma convenção,
Eu poderia ter usado algo mais na teoria.
E então, finalmente, deixe-me tentar ler o arquivo.
Então, deixe-me rolar para baixo.
E agora perceber isso é o lugar onde o código pode ficar um pouco confuso,
notar que eu estou chamando fs.readFile passagem
no mesmo caminho, a mesma callback como da última vez,
assim a versão anterior.
E então, se eu encontrar -
se eu não encontrá-lo, Eu cuspo de 500.
E se eu encontrá-lo, o que linha que vamos ver aqui?
Vamos ver os fs escrever cabeçalho 200 provavelmente
e um res.end envio os dados reais.
Mas perceber isso.
E isso não é demonstrativo do pior cenário.
Mas eu tenho esta chamada de estatísticas aqui do que eu tenho algumas coisas.
Então, eu tenho um outro chamada assíncrona aqui,
de modo mais recuo.
Assim, apenas uma espécie de extrapolar se pudesse partir daqui.
O problema tende a surgir com a linguagem como JavaScript
neste ambiente onde você não tem valores de retorno
mas você tem esses retornos de chamada.
E, claro, esta é apenas uma coisa estilística do fato
que eu continuo recuo.
Mas levar isso para o próximo passo lógico.
Suponha que houvesse um ou duas ou três outras funções
que eu precisava para executar esse éramos por natureza assíncrona,
e, portanto, apenas uma espécie de manter o recuo para lidar com eles,
lidar com eles, para lidar com eles.
Você fica com uma espécie de retorno de chamada inferno como as pessoas chamam de
onde o seu código começa a ficar muito grande
e, francamente, muito difícil de ler.
Como é, eu posso tipo de mal dizer que este é um tipo de fluxo
que tem esse tipo
de estilisticamente angular coisa acontecendo aqui.
Assim, este não é o ideal porque isso pode rapidamente tornar-se
pesado, apesar de dois assíncrona não exige
um negócio tão grande.
Então, nós poderíamos evitar isso, certo?
Você pode ter vislumbrado que Eu misclicked um momento atrás.
Na documentação, você sabe, parece que há statSync.
E statSync não leva um callback como argumento.
Leva apenas o caminho, porque ele aparentemente faz o quê?
Ele retorna uma instância de fs.stats.
Portanto, este pode ser o seu primeiro instinto, certo?
Especialmente se as funções de retorno de chamada
e asynchronicity é um pouco novo para você, francamente,
a abordagem mais fácil é, provavelmente, apenas evitar o problema todo
juntos, voltar para classificar de programação estilo CS101
onde você chamar função ou método, retorna o valor,
chamada de função, retorno o valor,
função, retorna o valor.
E eu poderia usar, portanto, fs.statSync
que é literalmente o mesmo mas é uma versão síncrona
o que significa que ele retorna o valor.
Ele não passa de um valor a um callback.
Mas por que isso provavelmente seria um solução sub-óptima de recorrer
para funções síncronas?
Sim?
[Inaudível Observação]
Exatamente, é preciso um longo tempo.
Você está apenas retardando tudo para baixo.
Porque assim como Shake Shack ou Burger saborosa, se eles se livraram
dessas campainhas e fez de você, o cliente ficar na parte da frente
de linha até que sua comida está pronta antes mesmo de tomar a ordem
da pessoa por trás obviamente você
através de venda diminui.
As pessoas começam a sair, você meio que desenhar pacotes.
Você pode fazer qualquer número de analogias aqui.
Mas, em suma, é provavelmente não é uma coisa boa
para o negócio ou para o servidor.
Então código assíncrono é geralmente bom, pelo menos
neste caso, mas definitivamente começa a causar alguma angústia.
E, de fato, me atrevo a dizer quando primeiro a escrever essas coisas,
isso vai demorar um pouco pouco de tempo para se acostumar.
Então, vamos começar a equipar lo com algumas bibliotecas
e técnicas para fazer isso um pouco mais fácil.
Assim, um dos mais comuns bibliotecas são bibliotecas populares
nos dias de hoje, este um chamado async.js.
E, assim como um monte de Node.js bibliotecas ou módulos,
estes são todos de código aberto.
Quase todos vivem e obter repositórios de cubo que é uma espécie
de tornar-se de facto lugar para guardar essas coisas.
E depois há um infra-estrutura de todo
para instalar essas coisas chamado NPM, Node Package Manager
que se você está familiarizado com EvanTube é uma espécie
de aplicativo como o aplicativo ou obter.
Se você estiver familiarizado com a Red Hat e Fedora
como no aparelho, é como yum.
Mas é um nó - é um gerenciador de pacotes apenas
para esse ambiente particular.
Então, a gente pode baixar e instalar coisas como a biblioteca assíncrona
e também um outro chamado o ressaltam biblioteca ou módulo.
Mas esses fs na medida, HTTP, caminho,
esses são todos vêm construído no nó.
Então, se vamos para a documentação da API, você realmente verá que construiu
em nó que você consegue de graça todo um conjunto de módulos.
Mas muita gente boa em a internet fizeram dezenas
se não centenas de outras bibliotecas
para fazer as coisas melhor ou de forma diferente.
Então, vamos dar uma olhada em como esta biblioteca funciona.
Assim, a maior parte deste código é idêntico para o momento.
Eu tenho um caminho a ser criado em cima.
E agora eu estou chamando async.series.
Assim, a biblioteca assíncrona, é apenas uma biblioteca que permite que você
passar ou aumentar tipicamente funções para se chamou um
após o outro apenas a espécie de evitar essa questão recuo,
e na verdade, apenas o mental angústia que invariavelmente surgem
pelo menos quando você mergulhar a este em seu próprio país
com programação de forma assíncrona.
Como em aparte, se tiver tomado 161 e que você lidou com fechaduras
e aumentar as condições e todos de que, o código assíncrono
e um ambiente como Node.js é realmente muito,
sem dúvida muito mais simples
do que realmente escrevendo código multithreaded.
Quando você tem código multithreaded,
você tem condições de aumento.
Você tem que se preocupar dois tópicos que contenham
pelos mesmos recursos disco ou memória.
A beleza de JavaScript
em Node.js é que há literalmente apenas um segmento,
o que significa que o navegador
ou o servidor só pode fazer uma coisa de uma vez.
É só até você, o programador
para manter um modelo mental para como uma espécie de fila coisas
e descobrir como para encomendar o seu código.
Mas você nunca tem que se preocupar sobre condições de levantar
exatamente da mesma maneira em menos com o código de Raw assim.
Então, é um pouco difícil Grack aqui.
Mas - Então deixe-me abrir a documentação para apenas um momento.
A biblioteca que async.js de forma semelhante é muito googleable,
ele vive no GitHub replantar como um monte deles.
Não acho que é esboçado, não é.
Deixe-me rolar para baixo para o Leia-me aqui.
Assim, a biblioteca assíncrona fornece um grupo inteiro
de métodos para dentro dele.
Por exemplo, não há um método chamado cada,
que se eu clicar isto apenas para ver seus documentos, por um momento,
esta é uma função ou método que permite que você faça alguma coisa
como um quatro cada mas em paralelo.
Eles estão todos indo para acontecer potencialmente em paralelo.
E o método de cada um é apenas vai voltar para você, quando tudo
das iterações estão completos.
Então, talvez eles acontecem um após o outro.
O ideal é que eles acontecem , essencialmente em paralelo.
Mas o método não faz chamá-lo de volta.
Não Buzz a sua campainha até todos
dos elementos que você tem iterado completou.
Então, é apenas uma maneira agradável
de evitar o uso quatro loop simples
mas realmente fazendo algo de forma assíncrona.
Mas agora mais diretamente relacionado com este exemplo,
notar que é isso Método série.
E deixe-me puxar para cima a exemplo canônico simples.
Assim, a bibliotecas assíncronos, série método leva em como se depreende
pelos colchetes na matriz.
Quais são os dados tipos de elementos
nesta matriz com base em um exemplo simples?
Esta é uma gama de funções.
Assim, em C, você chamaria eles funcionam ponteiros.
Em JavaScript, existem mais referencia adequadamente para funções
ou funções anônimas.
E isso apenas significa, matrizes
é claro que são ordenados de zero em cima.
Então, eles têm mantido uma ordem que é bom
para uma série, porque séries significa, naturalmente, fazer algo
a fim de não em paralelo.
Então, isso significa apenas que este função será executada,
em seguida, um presente, então este um, este, em seguida, um presente,
no entanto, há muitos
até que, finalmente, o opcional callback é chamado.
Então, observe o paradigma aqui.
E mesmo que esta é uma biblioteca de um cara,
é representativa da paradigma JavaScript muito comum
de novo usando callbacks.
Então, observe o que você faz aqui.
Na primeira função a ser aprovada em via essa matriz,
você definiu um anônimo função apenas com a função.
Mas note que, aparentemente, de acordo com esta documentação,
que função anônima deve tomar um argumento callback.
Isso vai ser um ponteiro ou uma referência a uma função
que você deve ligar quando sua código está pronto para retornar um valor.
Então, novamente, ao contrário de apenas programação tipicamente processual
onde você está acostumado a retornando valores imediatamente
que uma diferença com usando uma biblioteca como esta
na programação assíncrona mais geralmente, é quando você está pronto
para retornar um valor de um banco de dados, a partir de um arquivo,
a partir de uma operação aritmética expressão, cabe a você
para chamar a função de retorno de chamada.
E o bom sobre esta biblioteca
se lermos os documentos mais cuidadosamente é que,
se e somente se todos área de callbacks chamado
sem um objeto de erro, vai a coisa toda ter sucesso?
Assim, em outras palavras, se houver 2,
se há 10 anonymous funções
nesta matriz, portanto, nesta série,
somente se todos eles sucesso,
será o retorno de chamada final opcional ser considerado bem-sucedido?
Se qualquer um deles falhar, todas as funções
depois ele não vai mesmo ser executado.
Então, é uma boa maneira de tipo de ter uma cadeia
que aborta prematuramente se algo der errado.
Então, para ver isto no contexto, aqui É assim que pode re-implementar
que o programa anterior.
Recebo o caminho como antes, por isso esta é a parte fácil.
Eu copiar e colar este código esqueleto
a partir da documentação lá async.series parêntese aberto,
abrir colchete.
E agora notar que eu tenho uma função neste início
de um segundo, vamos ver para onde vamos a partir deste.
E agora percebe, é uma pouco complexo no início
mas se concentrar apenas em linha por linha.
Fs.stat significa obter as estatísticas ou o que não desse caminho.
Chame esse callback quando estiver pronto.
Este código é o mesmo que antes.
Se há um erro, há uma diferença agora.
Mais uma vez, o paradigma muito comum na programação Node.js é
se algo der errado e um callback precisa saber
que, por convenção, o primeiro argumento para uma chamada de retorno vai
não haver, se está tudo bem ou um referência a um objeto de erro,
capital de E. É como um erro classe que existe no mundo
mas mais sobre isso em outro momento.
Então, ao fazer isso, se há uma de erro, o que é a implicação?
Bem com base no que eu disse que a série faz,
é se alguma coisa der errado, nós só meio que quero
abortar toda a série função de chamadas anónimas.
Assim, é suficiente para mim basta retornar callback passagem
no objeto Error.
Porque se deu status me de volta um erro,
Eu poderia criar um novo Objeto de erro de minha autoria,
mas eu realmente não me importo de,
Eu só quero passar qualquer que seja o erro é que realmente acontece
para que eu possa passá-lo para este retorno.
E só para ficar claro, a retorno não é estritamente necessário.
Eu basicamente quero fazer isso mas eu queria agora fazer "regressar;
/ / De modo a que não mais código aqui executa ".
Então, novamente outra comum convenção em JavaScript,
mesmo que você não está retornar um valor em si,
Você quer passar o valor para a função de callback
mas então você quer para interromper a execução
da função que você está em, a maneira trivial
de fazer isso é apenas para chamar voltar aqui.
Mas não há nada de errado,
estamos apenas fazendo o retorno de chamada de retorno erro mesmo que ele vai
para retornar em valor indefinido.
Tudo bem, isso não retornar um valor mais provável.
Tudo que me importa é a embarque posterior execução.
Portanto, a minha fusão destes duas linhas é apenas um estilista
a convenção apenas para tem o número de linha
de código que eu acabei de escrever de 2 para 1.
Então, o que mais?
Se não houver um erro -
na verdade, para ser claro Eu também poderia evitar
que, ao fazer, se outra coisa.
Mas, novamente, outra paradigma comum é verificar
para os seus erros em cima e, em seguida, basta retornar ao invés de continuar
para recuar seu código com elses e elses e elses.
Então, se não é um arquivo, agora, você sabe,
Eu quero lidar com isso um pouco especialmente.
Então, aqui como em Java ou C + + ou algumas outras línguas,
veja aqui como pode instanciar um objeto para digitar passagem erro
em uma mensagem padrão de não um arquivo
e este é apenas um tanto arbitrária.
Mas eu estou sinalizando um erro meu.
E o que este último linha presumivelmente significa?
Tudo está bem.
Se você passar em nulo para o parâmetro de erro, que significa apenas
por convenção está tudo bem.
Então, isso significa que irá acontecer logicamente?
Se nulo é passado para o callback
isso significa que este anônimo função foi bem sucedida
por assim dizer.
Então, o que deve ser a série método precede e agora fazer com base
na minha definição verbal mais cedo?
[Inaudível Observação]
Passe para a próxima, né?
Se ele tinha voltado a não nulo valor, seria apenas abortar
e não mais anônima função seria chamado.
Mas, porque ele não tem, então esta será chamada seguinte.
Assim, a lógica aqui é praticamente o mesmo de antes
e vamos ver como limpar isso ainda mais em um momento.
Sei que isso é uma espécie de monte
para absorver tudo verbalmente e visualmente.
Mas agora percebe, o segundo função anônima que eu quero
para executar em série é para tentar ler o arquivo.
Chame esse callback quando estiver pronto.
Se houver um erro, apenas sinalizá-lo por meio do retorno de chamada
de modo que o resto este material aborta.
Return null Else.
Mas por que eu estou passando em dois argumentos?
Bem, desta vez, se eu ler o arquivo e voltar
como uma variável chamada de dados,
Quero não só significar tudo está bem, retornando nulo
para o primeiro argumento.
Quero voltar a real dados como o segundo argumento.
Porque se eu ler mais na documentação,
observar este último pedaço de código colchete significa que é a
fim da série.
Havia apenas dois anônimo funções nesta série.
Se houve um erro aqui, então Sei que um dos links
nesta cadeia, por isso falar falhou.
Assim, em outras palavras, este erro vai ser um objeto Error
que é nula se houver desses caras falhou.
E se esse for o caso, eu sou apenas vai socorrer e eu vou
quer dizer que 400 Significa pedido falhar,
isso é muito genérico mensagem de erro.
E então, eu vou imprimir a mensagem de erro.
Então, eu não vou dar ao trabalho de ser super anal desta vez,
Eu não estou indo para distinguir entre 500 e 404 e 403,
Eu sou apenas um tipo de cegamente acenar minha mão
e dizer algo deu errado.
Mas se nada deu errado,
Vou enviar esta res.end passando esses dados.
Agora isso parece um pouco enigmática.
Mas, novamente, se eu ler a documentação,
o segundo argumento para esse retorno de chamada final, final,
o cara que só é executado uma vez que o conjunto é feito
execução ou de uma parcela não de, este vai ser um array
de todos os argumentos segundo
que foram passados para o retorno de chamada.
Agora, descobre-se que o só ligar nesta série
que realmente retornar para a segunda argumento é este aqui.
Então eu vou para classificar de em um salto de fé simplesmente usar supõem
para o momento em que último é um método
que lhe dá a última elementos de uma matriz.
Porque essa matriz que está sendo passado
para mim tem duas indicies, zero e um.
É apenas a zero não tem valor porque esse cara retorna -
não passa em um segundo argumento, mas esse cara faz.
Assim resulta suporte zero não é nada,
resultados suporte um contém o que,
Se você tem seguido juntamente até esse ponto?
O arquivo, o Olá, conteúdo mundo presumivelmente,
então é assim que eu realmente imprimi-lo.
E deixe-me terminar um detalhe aqui.
Se eu fizer esse tipo de velho escola, se eu quero ficar
nos últimos elementos, se pudesse fazer resultados [results.length-1],
que é uma espécie de maneira da velha escola
de acessar os últimos elementos in - ou matriz índice zero.
Mas, como no lado, lembre-se que eu tive esta biblioteca
aqui sublinhado que por convenção é chamado apenas de
literalmente um sublinhado personagem que não é especial,
apenas parece legal como cifrão faz para jQuery.
Este é apenas um ajudante método ressaltam dot última
que faz exatamente a mesma coisa.
E se você nunca usei antes de sublinhar JS tanto
para a codificação do lado do cliente
e do lado do servidor é um biblioteca maravilhosamente útil
que o maior número de pessoas descritas ele gosta jQuery contém todas
dos métodos, as pessoas desejavam veio com o próprio JavaScript.
OK.
>> Assim, como muito para mim e Eu estava assistindo na série,
você tem como retorno de chamada como um argumento?
>> Sim.
>> Como assim, quando você realmente como impulso que nos,
e como o que faz dizer quando você só tem
como retorno de chamada e, em seguida, fazer como -
[Inaudível Observação]
>> OK, boa pergunta.
Então, deixe-me puxar para cima o async página principal aqui
ou a documentação sobre GetHub.
Então este é o canônico estrutura.
Se você estiver utilizando esta chamada nomeadamente série método,
há duas grandes peças para ele.
Um deles é uma série de funções anônimas
e dois é um retorno definitivo função que, na verdade,
executada no próprio fim da série.
Agora, se nós zoom em uma pouco mais no primeiro
desses grandes coisas, o conjunto de funções anônimas
por exigência deste documentação do cara tem
ser um anónimo função que recebe
em um argumento chamado callback ou foo ou bar, não importa
mas ele está chamando-o de retorno de chamada.
E este é o seu tipo de campainha Shake Shack que mãos você.
Este é o meio pelo qual você pode retornar um valor
para o cliente, porque você pode não apenas não literalmente voltar.
Você tem que fazê-lo por meio deste callback.
Porque, se dentro deste função alguma marcha lenta
código como banco de dados de consulta, leia o arquivo do sistema de arquivos,
você não quer esperar lá e bloquear todos os outros,
que deseja chamar o callback.
Então, isso é literalmente o nome do argumento.
Mas como em C, você tem ponteiros de função.
Em Java você tem métodos do sistema de referência
e mesmo aqui em JavaScript.
Esta é uma variável mas seu tipo é função.
Então, simplesmente por escrever seu nome se um retorno de chamada ou foo
ou bar, então parêntese aberto e fechar parênteses,
você está executando que em que a função.
E passar um nulo que significa erro nulo e um
o que significa que este é o dados que eu quero passar dentro
E, em seguida, o pedaço para ser claro, esta é uma outra callback.
E não é chamado de retorno de chamada,
apenas conceitualmente é um função método de retorno
porque ele é chamado por definição
da biblioteca do autor quando toda a série completou
ou subconjuntos dos mesmos, se um erro que aconteceu mais cedo.
Assim, o nome de função de retorno, chamando a função de retorno de chamada,
Nome da função de retorno, chamando a função de retorno de chamada,
callback diferente funcionar em conjunto.
>> Temos, agora, como definir callback?
>> Não, porque esse cara vai passar em sua matriz
funções de anônimos,
um ponteiro para o código ele quer executar.
Exatamente, tudo bem.
Então, por favor, dizer que o código fica um pouco mais simples.
Assim, ele pode.
E se você é como eu, tomar conforto em, pelo menos, sabendo,
leva um tempo para se acostumar com isso.
Mas podemos limpar isso um pouco,
para não jogar muito no que você mas aqui está uma outra variação
e seu outro método
na mesma biblioteca chamado cachoeira.
O lado positivo de que é ao contrário séries onde cada
daqueles anónimo funções executadas essencialmente
independentemente cada um dos outros.
Cachoeira, como o nome sugere permite que as funções superiores
a espécie de passar valores para a função inferior,
Mais ou menos como uma cascata de água.
Assim, a vantagem deste é que eu posso tipo
de usar isso a meu favor.
Em async.waterfall, notar o seguinte.
Eu só posso chamar fs.stat passando o caminho
que eu quero ficar estatísticas sobre.
E, em seguida, lembre-se antes de eu tinha uma função anônima
que tinha dois argumentos errar,
esultados e depois liguei para o função de retorno manualmente?
Em outras palavras é apenas para ser claro, lembre-se que no início
em assíncrono 2, eu fiz tudo deste trabalho desagradável.
Liguei fs.stat aprovada em P,
declarou o meu próprio anônimo função.
Eu, então, verificado se o erro é não nulo, então eu fiz isso,
mais eu fiz isso, todo o beleza de seguir convenções
como em Node.js é que callback as funções em geral são destinadas
ter pelo menos um argumento, um objeto de erro seguido por zero
ou valores mais úteis.
Então, observe o paradigma aqui,
essa função de retorno de chamada que estou declarando segue exatamente o
paradigma que esse cara biblioteca assíncrona faz.
O que quer dizer isso, por que sou Eu implementar minha própria callback
método quando o autor deste biblioteca é, literalmente, entregando-me
em uma bandeja por assim dizer, um função de retorno que posso usar?
Então, eu só posso passar no referenciar ele me deu
de modo que, imediatamente, minhas várias linhas
de código tornam-se uma linha de código.
Agora, para onde vamos com isso?
A próxima função que Eu quero executar,
a próxima anônimo função neste conjunto
de funções faz o seguinte.
Aviso primeira status é o primeiro argumento.
Então, alguma coisa tem já mudado.
Agora, esse cara que escreveu a biblioteca -
e eu estou dizendo cara porque ele é um cara.
Esse cara que escreveu esta biblioteca é garantia de documentação
que, se esta função aqui me passa para trás um objeto Error
ou nula seguido por coma lista separada de outros valores,
ele vai ter certeza de que aqueles outros valores são entregues
para esta função anônima em ordem da esquerda para a direita.
E o que era para ser apenas um função de retorno sozinho simplesmente
torna-se o último tal argumento.
Agora, eu não sei quem eu sou focando apenas sabe.
Mas agora, qual é o tirar daqui?
Então, sabemos que a partir de documentação
ou o par anterior de exemplos
que em última análise, espera fs.stat uma chamada de retorno com dois argumentos,
o objeto de erro, que é um Objeto erro ou nulo seguido
por uma referência ao objeto de estatísticas.
Então, se eu pensar sobre isso, Objeto de erro estatísticas coma objeto,
que se encaixa no paradigma de biblioteca dessa pessoa.
Então, eu posso simplesmente dizer porque Eu já o segundo argumento
que é - o que está acontecendo para ser aprovada pelo fs.stat
para o callback é err, estatísticas por definição desta biblioteca,
Eu posso colocar o segundo o nome do argumento aqui
ou o que eu posso mudar o nome
se eu quiser seguido pelo retorno de chamada aqui.
Então, eu posso passar um valorizar daqui até aqui.
Agora, todo este código embora reconhecidamente um tanto enigmática é
pelo menos copiar e colar para Na maior parte de antes.
A única diferença é aviso aqui eu estou declarando um erro
objeto e agora eu quero a ficar um pouco mais extravagante.
Na verdade, eu quero saber o que o erro foi, então eu vou
para dobrar dentro desse objeto uma propriedade arbitrariamente chamado código
por isso que eu sei que este não é um arquivo
que deve ser autorizada, é um HTTP 403.
Deixe-me lembrar que antes Eu passar o objeto de erro
para o retorno de chamada.
E então, finalmente tentar ler o arquivo, portanto, neste caso,
da cachoeira, eu quebrei o código de dois grandes etapas
em três passos menores.
Observe a beleza aqui,
Eu posso chamar fs.readFile passando o caminho.
E, em seguida, a parte mais difícil mentalmente, é que eu apenas passar
em callback do cara.
A única coisa que ele está me dando, eu estou vai passar a fs.readFile.
Porque todos nós estamos aderindo para as mesmas convenções,
primeiro argumento para uma chamada de retorno é um objeto de erro ou nulo seguido
por coma ou separados lista de coisas úteis.
Então, o que significa que agora, e se eu leia a documentação eu saberei
este, o último retorno, esse cara aqui fora
dos colchetes está acontecendo para ser passado em objeto de erro
ou nula, que eu deveria verificar se há como sempre, com esse código aqui.
E, em seguida, por definição deste método
na documentação do rapaz, o último valor devolvido
a partir do último método na minha matriz anônimo -
meu leque de funções anônimas.
Então, o que ler arquivo retorno
e eu estou usando um retorno vagamente agora.
Quero dizer que não lê arquivo passe como argumentos
para o método de retorno de chamada sua mão?
Dois argumentos, o primeiro é um objeto de erro ou nulo,
que é quase sempre vai ser a resposta.
E a segunda coisa está acontecendo para ser o que para arquivo de leitura?
O conteúdo do ficheiro, dados como a chamávamos antes.
Então, simplesmente declarando err, resultar,
e verificar se há erro esta é uma espécie de chato agora.
Outra coisa, eu faço res.end passando esse resultado.
Este, sem dúvida, não sincronizar perfeitamente
até que você realmente escrevê-lo sozinho.
Mas, por agora, tomar embora pelo menos o facto
que haja, aparentemente, esta paradigma comum, pelo que se
e autores de bibliotecas todo o tipo de vara
com esta convenção de métodos de retorno de chamada.
E o primeiro argumento é um objeto de erro ou nulo.
E a segunda e terceira
e quarta objetos são coisas nós nos preocupamos e que tipo
de seguir as regras e documentação.
Começamos com um código que honestamente é muito feio.
E mesmo que o mais recente exemplo é francamente um pouco difícil
para envolver sua mente em torno, é pelo menos visualmente,
parece que é muito mais apertado.
E uma vez que você se sentir confortável com isso, é muito mais fácil
e é muito menos propenso a bugs do que esse exemplo anterior.
Então, deixe-me demonstrar uma última coisa aqui.
Esta é a versão três.
E - Não, vamos deixar este sozinho.
Deixe-me entrar em um par de outros últimas coisas como teasers.
Tudo bem, então no servidor 2.
OK. Em primeiro lugar, qualquer dúvida, Sei que isso é muito
mas você queria mais instruções, e daí?
Você não disse boa instrução necessariamente.
Sim?
[Inaudível Observação]
Correto, você está essencialmente leniente para sistema operacional
para descobrir como fazer malabarismos todas estas bolas ao mesmo tempo,
a leitura de um arquivo, ler a partir de uma base de dados.
E é este servidor JavaScript em si que é único segmento.
E, essencialmente, e na verdade,
há uma imagem Eu não vomitar,
e não é necessariamente tudo o que esclarecedor
mas talvez nós vamos dar você um modelo mental.
JavaScript si e nó
em particular, tem esta chamado ciclo de eventos.
Pelas quais, você pode pensar de node.js, o programa,
é literalmente como um loop infinito.
É apenas um loop selvagem, esperando e esperando e esperando,
procurando tarefas para completar.
E a tarefa pode ser, vá buscar algo a partir de um banco de dados
ou aqui está um valor da banco de dados ou ir buscar este arquivo
de disco ou aqui está um solicitar de um usuário.
Qualquer tipo de evento, assim como caso navegadores conduzido,
assim como o servidor evento paralelo conduzido.
E nenhuma dessas coisas constituem eventos.
Então alguém em Node.js, apenas escreveu um loop infinito,
um grande laço selvagem, esperando para coisas a acontecer.
E, como coisas que acontecem, acaba em uma fila, certo?
Certamente, uma base de dados pode retornar um valor.
E um sistema de arquivos, o funcionamento sistema pode retornar um valor
mais ou menos ao mesmo tempo Mas há, provavelmente, vai
de haver alguma ordem para eles.
E node.js vai ter essencialmente uma fila
como uma grande matriz ou um vector, alguma estrutura de dados
que buffers tudo dessas coisas.
Porque ele pode literalmente apenas lidar com um deles de cada vez.
Assim, quando você, o desenvolvedor,
escrita assíncrona JavaScript código usando assíncrono
função, você está permitindo que este o chamado ciclo de eventos para ir
para a próxima escala, certo?
Então, desde que você imediatamente regresso se tudo
destes métodos assíncronos fazer como arquivo de leitura e estatísticas,
eles retornam imediatamente porque o retorno de chamada, eventualmente,
recebe de volta.
Assim que você voltar,
isso significa que alguém pode se bateu fora o estoque aqui
ou que ele pode ficar bateu fora na frente da fila aqui.
E assim, há em fato de a serialização
de tudo o que está acontecendo,
apesar de todas estas coisas pode estar acontecendo em paralelo
em um sistema de vários segmentos.
Mas node.js si e o servidor estava executando
como um segmento.
E o lado ruim disso é t você não necessariamente max
o seu computador de capacidade é como especialmente
se você tem um núcleo de 16 ou até mesmo um computador 2 núcleos
e você está correndo uma instância do nó.
Mas se você tiver outra vez tomado algo como 161,
a evitar um enorme pesadelo de dores de cabeça quando se trata
a condições de corrida e fechaduras e semáforo
e escrever realmente o código multithreaded,
assim prós e os contras.
OK. Então, de volta para o código aqui, deixe-me propor que comecemos
para simplificar as coisas um pouco.
Vimos um servidor um pouco atrás, que ficou assim.
Então, isso é, sem dúvida, muito simples.
Mas, assim como no mundo do PHP, existem enquadramentos
como Laravel e há coisas como Rails e Django,
mesma coisa no mundo node.js.
E nós vamos gastar mais tempo nesta quarta-feira
e no próximo projeto.
Mas se eu entrar em um 2 servidor de diretório,
notar um par de paradigmas aqui.
Portanto, esta é - não vai ser um exemplo equivalente
mas ele está usando um quadro chamado express.js,
que é livre de código aberto software como o Rails e Django,
como Laravel, isso é apenas vai, em última instância
ser desvalorizado hoje Porque nós temos escrito
tais exemplos simples.
Mas confie em nós.
Isso vai muito rapidamente tornar-se seu amigo
porque você vai economizar você um monte de código TDS.
E um paradigma comum para uma aplicação é express.js
ter um ou app.js server.js arquivo que contém a lógica
do seu programa ou pelo menos, o ponto de entrada.
Você pode ter vários arquivos.
Um módulo subdiretório nó que tem as bibliotecas
que você baixou como assíncrono
e expressar-se em outros.
E então package.json, package.json se parece com isso,
e você pode criá-lo manualmente ou ferramentas de criá-lo para você
e é literalmente um arquivo json
ea parte interessante é as dependências aqui.
Assim como em Laravel, você tinha esse diretório fornecedor
e você tinha que se preocupar sobre os pacotes e fazer -
realmente atualizar com Artisan ou comandos semelhantes,
as bibliotecas que você instalou,
da mesma forma com package.json aqui e gerenciar as bibliotecas
e as versões que você se preocupa.
Então, se eu tenho um package.json, Posso simplesmente fazer NPM,
Node Package Manager instalar, ele vai procurar automaticamente
naquele arquivo package.json.
Olhe e veja, eu ter a última versão
de todos os módulos de fornecedores
em um nó de sublinhar módulos diretório aqui ou talvez
em algum progenitor, ou diretório ancestral.
E se não, é vai baixá-los
e você vai ver um grupo inteiro
de coisas acontecendo HTTP através do fio.
Assim, por exemplo, deixe-me mostrar-lhe o conteúdo
de módulos de nós apenas para expressar.
Deixe-me ir em frente e corajosamente excluir módulos nó
de modo que tudo o que eu tenho agora é este.
E se eu NPM instalar, você vai ver que ele vai ler
esse arquivo e package.json vimos uma saída similar
para isso no mundo Laravel.
Tem de baixar um todo monte de coisas e isso é
porque expressa por sua vez, depende de um grupo inteiro
de outras bibliotecas pessoas.
Assim, todos aqueles que são uma espécie de sendo baixado de forma recursiva.
Até agora, se eu fizer em LS, novamente,
há meus módulos nó diretório de volta
e expressar como de volta.
Por isso, é apenas uma forma de simplificando o gerenciamento de pacotes.
Agora, se olharmos para o arquivo app.js, isso vai
ser uma reversão ao o nosso servidor web mais antiga
onde apenas cuspir fora "Olá, mundo".
Mas observe os paradigmas aqui,
primeiro exigimos o expresso módulo, então temos esta linha
de código que você sabe a partir da documentação.
Você literalmente tratar essa variável do módulo como uma função,
tão aberto parêntese perto parêntese significa executá-lo.
Isso vai, aparentemente, retornar algo que vamos
geralmente chamamos de um app.
Como ele funciona?
Eu realmente não sei.
Vou deixar que outra pessoa, você sabe, no mundo expressa escrever isso.
Vou agora ficar em seus ombros, de modo
para fazer minha aplicação correndo um pouco mais simples.
Aqui, eu vou ouvir nessa porta especial
que poderia ser qualquer coisa.
E aqui está o código que é talvez mais uma reminiscência agora
de Laravel e routes.php.
Portanto, esta é a ceia simples, eu sou só vai para especificar uma rota
para a estrela barra, então tudo vai ser absorvido
por este manipulador de solicitação.
O paradigma para manipulador de solicitações é a sua função anônima
com um argumento pedido
e um objeto de resposta como antes.
E res.send em meio expressas de enviar o código seguido
por tudo o que você deseja enviar.
E, claro, você pode fazer algo mais sofisticado
por realmente enviando arquivos ou HTML
ou gerados de forma dinâmica conteúdo.
Mas, por agora, tudo o que fizemos foi cuspir Olá, mundo.
Se formos para servidor três, isso é ainda mais extravagante apenas
mostrar-lhe algumas funcionalidades.
E nós vamos mostrar-lhe um versão ainda mais sexy
desta quarta-feira.
Mas se você nunca ouviu falar de soquete IO talvez,
assim como eu acho que Jonathan ou alguém disse anteriormente,
uma das coisas nó é muito conhecido
para é o seu tempo real comportamento, certo?
Pense em PHP em MySQL, se você foram para implementar um servidor de chat
em PHP em que duas pessoas poderiam abrir uma janela do navegador para foo.com
e, em seguida, começar trocando mensagens cada outro, Alice em uma janela,
Bob na outra, de modo que cada um deles vê a sua
ou suas mensagens a outra janela.
Como você faria isso em PHP e MySQL?
Usar ou não usar Laravel tipo do imaterial, você pode ter
como um arquivo index.php.
E você tem que ter - em alguns casos, tem que cuspir
fora de forma, então não há vai ser um formulário HTML
que, provavelmente, não submete por finalização forma normal
mas, provavelmente, Ajax, certo?
Assim, um manipulador em enviar, assim que você digita em um campo de texto,
você aperte enter e, em seguida, ele fica enviado ao servidor via Ajax.
O que você faz, em seguida, fazer no servidor?
Então, você tem index.php
ou algo dot PHP que é recebida no parâmetro HTTP
do usuário, de Alice ou de Bob mensagem instantânea, o que você faz
com ele, a fim de propagá-la para Bob ou Alice, respectivamente?
Quer dizer que você, literalmente, ter as ferramentas com as quais
para fazer isso no seu min.
Assim como o que você faria?
Você tem um minuto para implementar este programa.
Sim?
[Inaudível Observação]
Perfeito. Certo, então você tem um banco de dados.
Sabemos um pouco pouco sobre MySQL.
Assim, você tem uma tabela isso é mensagens,
Talvez haja uma vezes selo, um ID de usuário,
o corpo da mensagem si criado que,
atualizado que e tudo isso.
Assim, você pode armazenar em um banco de dados.
E suponha que Alice envia a primeira mensagem, como é que Bob obter
essa mensagem agora a partir da base de dados?
>> Pode ser algum Ajax resposta que está acontecendo constantemente
de volta para o banco de dados top obter o [inaudível].
>> Exatamente.
Assim, o código do Bob que é código é o mesmo que Alice é apenas uma espécie
de uma relação simétrica,
Navegador de Bob tem algum código Ajax isso é provavelmente talvez a cada 30
segundos puxando o servidor via Ajax sincronia,
existem novas mensagens?
Há novas mensagens?
A cada 30 segundos vai para ser uma espécie de sub-ótima
porque ele tem que esperar ainda
Alice se literalmente apenas enviou a mensagem.
Então, o navegador de Bob poderia cada segundo bateu o servidor.
Mas isso significa que Alice navegador está atingindo o servidor
a cada segundo.
E sobre Charlie [Ortografia assumido]
e David [assumido ortografia] e Edward [assumido ortografia]
e todas as outras letras do alfabeto?
Qual é o problema desta abordagem?
Um grande número de acessos excessivos -
Quero dizer que você é apenas eficaz Dosagem sua própria visão
ou DDOSing, distribuída Ataque de negação de serviço
em seu próprio site, fazendo com que todos
desses usuários executar JavaScript código que é apenas o ping do
Parreira fora do seu servidor mesmo número arbitrário,
80 por cento do tempo ninguém disse nada
na sala de chat.
Mas você está apenas verificando para certificar-se de tal.
Então PHP em um monte de línguas não são apenas bom
para comunicações em tempo real.
Porque em recordação PHP há nenhuma memória central, certo?
Você tem objetos de sessão o que cria a ilusão
de armazenamento central, mas isso é em uma base por usuário.
Você não tem memória global como você faz em um Java Servlet
em familiares ou em outro quadro funciona assim.
Node.js, porém, você tem memória global porque você tem
um servidor e que "pode lembre-se o que quiser
sobre todos os usuários.
E você ainda pode tem uma base de dados.
Mas a coisa agradável sobre node.js também é que é muito melhor
do que algo como PHP e criando a ilusão
de lidar com múltiplas coisas ao mesmo tempo.
E, de fato, como na de lado, você pode implementar servidores de bate-papo em PHP,
mas você faria normalmente algo chamado long polling
pelo qual você não pingar o servidor a cada segundo.
Você ping do servidor, o servidor não responde a você
por mais de 30 segundos, ele literalmente se senta
em um loop esperando e esperando.
E o servidor verifica se há novos dados no banco de dados
e só uma vez que você vê: "Oh, aqui está uma mensagem de Bob ",
ele responder ao servidor HTP?
Assim, o efeito no seu navegador é que o ícone do IE ou Mozilla
ou o que só continua girando durante 30 segundos de cada vez.
Mas o lado positivo é que você não fazer tem 30 pedidos de ligação
em 30 segundos, você tem um.
Então, ele é chamado de comprimento de voto.
Mas o melhor mesmo na web moderna navegadores é algo chamado
WebSocket, que você pegar o CS143,
você pode efetivamente fazer uma Conexão TCP de um cliente
como um navegador para um servidor e depois segurá-la
sem o uso de quase tantos recursos
como HTTP tradicionalmente pode fazer.
E Soquete IO é uma biblioteca Node.js
que o torna muito mais fácil fazer as conexões de soquete
ou ilusões lá no para navegadores antigos
de modo que você pode implementar essa funcionalidade de tempo real.
Então, aqui está um exemplo.
Este material em cima fica um pouco mais complicado
mas é principalmente copiar e colar de documentação socket.io 's.
Aqui está agora mais manipulador de solicitação precisa.
Se o pedido de um utilizador slash, o arquivo que eu vou
ser aparentemente servir-se a eles?
Index.html.
E há alguma nova coisas aqui córrego
que eu vou lhe mostrar em apenas um momento.
Mas esta é apenas uma outra maneira
de pegar um arquivo de um pouco mais eficientemente
do que simplesmente fazer fs.readFile.
É um pouco mais inteligente especialmente para arquivos grandes.
Assim, longa história curta, estas linhas apenas para servir
um arquivo chamado index.html
que por agora assumir contém o formulário HTML pelo qual Alice
e Bob pode se intercomunicam.
Por último, io.sockets.on, então isso vem dessa linha aqui.
Então, eu só estou lendo o documentação io.socket me dá
acesso a uma chamada WebSocket com um navegador,
entre o navegador e o servidor.
Estou ouvindo para especial conexão evento que meios
quando o usuário primeiro atinge o servidor tentando
para abrir esta conexão, eu sou vai chamar esta chamada de volta.
E agora, eu vou para fazer o seguinte.
A cada cinco segundos, o que eu vou fazer?
Eu estou indo para emitir ou transmitir se você se lembrar do zero,
a linguagem gráfica seria que o de blocos de transmissão?
Então, você está indo para emitir
ou desencadear um evento chamado arbitrariamente a partir do servidor.
E isso vai conter uma mensagem Ping
ea data atual.
Então, esta é uma real servidor de chat que Alice
e Bob pode usar, mas é uma espécie de um servidor de bate-papo automatizado
onde as mensagens são pings apenas uma espécie de sonar.
É apenas a data em tempos que são ser enviada a cada cinco segundos.
Então, se eu realmente executar este coisa - e é isso.
Para ser claro aqui, aviso este é apenas o login aqui.
Então, deixe-me voltar um olhos para isso.
Deixe-me fazer nó de app.js.
Deixe-me ir para o meu browser.
Atualizar a página inicial aqui.
[Pausa]
E deixe-me fechar o inspetor.
A cada cinco segundos, eu tenho um demonstração, mesmo que não
interativa para o ser humano
de algo que é acontecendo de forma assíncrona.
No aviso de navegador, não há nenhum ícone de spinning.
Ele está usando um recurso mais sofisticado do Chrome em navegadores modernos
de manutenção de um soquete conexão debaixo do capô
e é o que é chamado geralmente um modelo de pub / sub,
publish / subscribe modelo, onde não temos feito
que muito explicitamente aqui.
Mas o que é agradável sobre este pub geral / sub paradigma é
que você pode ter uma editora.
Neste caso, o servidor central e todos
do indivíduo navegadores são clientes.
Alices e Bobs da mundo podem inscrever-se nele,
para que você possa retransmitir mensagens entre qualquer número de usuários.
E mesmo que novamente estamos não ver a interatividade,
tivemos talvez 12 linhas de código apenas para fazer isso.
E provavelmente não é um salto imaginar como você pode chicotear
o arquivo index.html que tem um formulário HTML verdade,
pouco de código jQuery com Ajax que não envia um dia
mas apenas envia o que quer que Alice ou tipo Bob para o servidor
e, em seguida, o servidor irá retransmiti-lo para fora.
E eu prometo a vislumbrar em uma última coisa só
provocá-lo com isso.
Se formos para a corrente zero e um,
você vai ver um código que é apenas um pouco diferente aqui.
Só assim você já viu isso, esta é uma alternativa
para o que chamei de fs.readFile método anterior, em que,
você pode dizer node.js: "Vá ler este arquivo para a memória.
Mas se é grande apenas dar me um pedaço de cada vez. "
E você pode saber a partir de CS165
ou 161 os sistemas de arquivos ter diferentes
propriedades de desempenho.
Você pode querer ler em blocos de 512 bytes
ou 2 kilobytes ou qualquer outra coisa.
Esta é uma maneira de otimizar voltando de arquivo de forma iterativa
de modo que você pode cuspir um pouco mais rapidamente
para o navegador ou quem quer que o cliente final é.
Então enorme quantidade de conteúdo hoje e vamos mergulhar
em mais detalhes na quarta-feira com Tim [ortografia assumido]
em particular olhando como nós pode traduzir algumas das idéias
a partir da primeira metade do Claro Laravel e modelos
numa biblioteca que ele próprio escreveu chamado Bookshelf.js
que se tornou cada vez popular na comunidade
porque lhe dá mais do mesmo,
se não mais do que a funcionalidade do eloqüente
que recall é que percepção biblioteca de Laravel,
de modo mais sobre isso e muito mais como
desenvolver pleno direito aplicativos na quarta-feira.
Vamos ver você em seguida.