O que é o Node.js? [fechadas]


506

Não entendo completamente o que é o Node.js. Talvez seja porque eu sou principalmente um desenvolvedor de aplicativos de negócios baseado na Web. O que é e para que serve?

Até agora, meu entendimento é o seguinte:

  1. O modelo de programação é orientado a eventos, especialmente a forma como ele lida com I / O .
  2. Ele usa JavaScript e o analisador é V8 .
  3. Pode ser facilmente usado para criar aplicativos de servidor simultâneos.

Meus entendimentos estão corretos? Se sim, quais são os benefícios da E / S registrada, é apenas mais para o material de simultaneidade? Além disso, é a direção do Node.js para se tornar uma estrutura como o modelo de programação baseado em JavaScript (baseado em V8)?

Respostas:


213

Eu acho que as vantagens são:

  1. Desenvolvimento da Web em uma linguagem dinâmica (JavaScript) em uma VM incrivelmente rápida (V8). É muito mais rápido que Ruby, Python ou Perl.

  2. Capacidade de lidar com milhares de conexões simultâneas com sobrecarga mínima em um único processo.

  3. O JavaScript é perfeito para loops de eventos com objetos de função de primeira classe e fechamentos. As pessoas já sabem como usá-lo dessa maneira, tendo usado no navegador para responder a eventos iniciados pelo usuário.

  4. Muitas pessoas já sabem JavaScript, mesmo pessoas que não afirmam ser programadores. É sem dúvida a linguagem de programação mais popular.

  5. O uso de JavaScript em um servidor da Web e no navegador reduz a incompatibilidade de impedâncias entre os dois ambientes de programação que podem comunicar estruturas de dados via JSON que funcionam da mesma forma nos dois lados da equação. Código de validação de formulário duplicado pode ser compartilhado entre servidor e cliente, etc.


1
@postfuturist: Na verdade, ele tem um bom desempenho contra muitas alternativas. Ele também supera o Java 6 com bastante facilidade em muitos casos. Arrumado!
Adam Crossland

1
@postfuturist Eu acho que você comparou com o java 6 -Xint. Tente comparar com java 6 -server
fedesilva

@iJK yammer.com é uma aplicação de trabalho de node.js
Gerard Banasig

1
Engraçado, eu estava escrevendo JScript no ASP há 10 anos, para que eu pudesse (a) evitar a imensidão do VBScript, (b) usar a mesma linguagem no cliente e no servidor e (c) reutilizar minhas bibliotecas JS próprias e de outras pessoas para manipulação de cordas ... etc.
Antony Quinn

4
@Por que você editou esta postagem apenas para "besteiras herdadas"? Eu não acho que 212 pessoas votariam neste post se você o escrevesse desde o início.
Julien Fouilhé 19/10/12

619

Uso o Node.js no trabalho e considero muito poderoso. Forçado a escolher uma palavra para descrever o Node.js, eu diria "interessante" (que não é um adjetivo puramente positivo). A comunidade é vibrante e crescente. O JavaScript, apesar de suas peculiaridades, pode ser uma ótima linguagem para codificar. E você repensará diariamente sua própria compreensão das "melhores práticas" e dos padrões de código bem estruturado. Há uma enorme energia de idéias fluindo para o Node.js agora, e trabalhar nele expõe você a todo esse pensamento - excelente levantamento de peso mental.

O Node.js em produção é definitivamente possível, mas longe da implantação "pronta", aparentemente prometida pela documentação. Com o Node.js v0.6.x, o "cluster" foi integrado à plataforma, fornecendo um dos componentes essenciais, mas meu script "production.js" ainda possui ~ 150 linhas de lógica para lidar com coisas como criar o log diretório, reciclagem de trabalhadores mortos, etc. Para um serviço de produção "sério", você também precisa estar preparado para limitar as conexões de entrada e fazer tudo o que o Apache faz para PHP . Para ser justo, o Ruby on Rails tem esse problema exato . É resolvido através de dois mecanismos complementares: 1) Colocando Ruby nos Rails / Node.Apache / Lighttd ). O servidor da web pode servir com eficiência conteúdo estático, acessar log, reescrever URLs, encerrar SSL , impor regras de acesso e gerenciar vários sub-serviços. Para solicitações que atingem o serviço do nó real, o servidor da web realiza proxy da solicitação. 2) Usando uma estrutura como o Unicorn, que gerenciará os processos de trabalho, reciclá-los periodicamente, etc. Ainda não encontrei uma estrutura de serviço do Node.j que pareça totalmente preparada; pode existir, mas ainda não o encontrei e ainda uso ~ 150 linhas no meu "production.js" enrolado à mão.

Estruturas de leitura como o Express fazem parecer que a prática padrão é servir apenas tudo através de um serviço Node.js. de todos os tipos ... "app.use (express.static (__ dirname + '/ public'))" . Para serviços e desenvolvimento de carga menor, provavelmente isso é bom. Porém, assim que você tentar colocar um carregamento pesado em seu serviço e executá-lo 24 horas por dia, sete dias por semana, você descobrirá rapidamente as motivações que levam os sites a criar códigos C bem endurecidos e endurecidos, como o Nginx, na frente do site e na manipulação de todos os sites. das solicitações de conteúdo estático (... até você configurar uma CDN , como o Amazon CloudFront )). Para uma opinião um tanto humorística e descaradamente negativa, veja esse cara .

O Node.js também está encontrando cada vez mais usos não relacionados a serviços. Mesmo se você estiver usando outra coisa para veicular conteúdo da Web, ainda poderá usar o Node.js como uma ferramenta de construção, usando módulos npm para organizar seu código, Browserify para costurá-lo em um único ativo e uglify-js para minimizá- lo para implantação . Para lidar com a web, o JavaScript é uma correspondência perfeita de impedância e freqüentemente a torna a rota de ataque mais fácil. Por exemplo, se você deseja analisar várias cargas úteis de resposta JSON , deve usar meu módulo CLI de sublinhado , o cinto de utilidades dos dados estruturados.

Prós e contras:

  • Profissional: para um servidor, escrever JavaScript no back-end tem sido uma "droga de gateway" para aprender padrões modernos de interface do usuário. Não tenho mais medo de escrever o código do cliente.
  • Pro: tende a incentivar a verificação adequada de erros (o erro é retornado por praticamente todos os retornos de chamada, incomodando o programador; também, async.js e outras bibliotecas lidam com o paradigma "falhar se alguma dessas subtarefas falhar" muito melhor do que o código síncrono típico )
  • Pro: algumas tarefas interessantes e normalmente difíceis tornam-se triviais - como obter status das tarefas em andamento, comunicar-se entre trabalhadores ou compartilhar o estado do cache
  • Pro: comunidade enorme e toneladas de ótimas bibliotecas baseadas em um sólido gerenciador de pacotes (npm)
  • Con: JavaScript não tem biblioteca padrão. Você se acostuma a importar funcionalidades que parecem estranhas quando você usa o JSON.parse ou algum outro método de compilação que não requer a adição de um módulo npm. Isso significa que existem cinco versões de tudo. Até os módulos incluídos no "núcleo" do Node.js. possuem mais cinco variantes, caso você não esteja satisfeito com a implementação padrão. Isso leva a uma evolução rápida, mas também a um certo nível de confusão.

Versus um modelo simples de um processo por solicitação ( LAMP ):

  • Pro: escalável para milhares de conexões ativas. Muito rápido e muito eficiente. Para uma frota da web, isso pode significar uma redução de 10 vezes o número de caixas necessárias em comparação com PHP ou Ruby
  • Pro: Escrever padrões paralelos é fácil. Imagine que você precisa buscar três (ou N) blobs do Memcached . Faça isso no PHP ... você acabou de escrever o código que busca o primeiro blob, depois o segundo e o terceiro? Uau, isso é lento. Há um módulo PECL especial para corrigir esse problema específico do Memcached, mas e se você quiser buscar alguns dados do Memcached em paralelo com a sua consulta ao banco de dados? No Node.js, como o paradigma é assíncrono, é muito natural ter uma solicitação da Web para fazer várias coisas em paralelo.
  • Contras: O código assíncrono é fundamentalmente mais complexo que o código síncrono, e a curva de aprendizado inicial pode ser difícil para os desenvolvedores sem uma compreensão sólida do que a execução simultânea realmente significa. Ainda assim, é muito menos difícil do que escrever qualquer tipo de código multithread com bloqueio.
  • Con: Se uma solicitação de uso intensivo de computação for executada por, por exemplo, 100 ms, interromperá o processamento de outras solicitações que estão sendo tratadas no mesmo processo Node.js. ... AKA, multitarefa cooperativa . Isso pode ser mitigado com o padrão Web Workers (desmembramento de um subprocesso para lidar com a tarefa cara). Como alternativa, você pode usar um grande número de trabalhadores do Node.js. e apenas permitir que cada um lide com uma única solicitação simultaneamente (ainda bastante eficiente porque não há reciclagem do processo).
  • Contras: A execução de um sistema de produção é MUITO mais complicada do que um modelo CGI como Apache + PHP, Perl , Ruby , etc. Exceções não tratadas derrubarão todo o processo, exigindo lógica para reiniciar os trabalhadores com falha (consulte o cluster ). Módulos com código nativo de buggy podem travar o processo com dificuldade. Sempre que um trabalhador morre, todas as solicitações que ele estava manipulando são descartadas; portanto, uma API de buggy pode degradar facilmente o serviço para outras APIs hospedadas.

Contra escrever um serviço "real" em Java / C # / C (C? Sério?)

  • Pro: Fazer assíncrono no Node.js é mais fácil do que fazer segurança de encadeamento em qualquer outro lugar e, sem dúvida, oferece maiores benefícios. O Node.js é de longe o paradigma assíncrono menos doloroso em que já trabalhei. Com boas bibliotecas, é apenas um pouco mais difícil do que escrever código síncrono.
  • Pro: sem erros de multithreading / locking. É verdade que você investe com antecedência escrevendo códigos mais detalhados que expressam um fluxo de trabalho assíncrono adequado, sem operações de bloqueio. E você precisa escrever alguns testes e fazer com que tudo funcione (é uma linguagem de script e nomes de variáveis ​​de dedilhado em gordura só são capturados no momento do teste de unidade). MAS, uma vez que você o faz funcionar, a área de superfície para os erros de heisenbugs - problemas estranhos que só se manifestam uma vez em um milhão de execuções - é uma área muito menor. Os impostos que escrevem o código Node.js. são fortemente carregados com antecedência na fase de codificação. Então você tende a acabar com um código estável.
  • Pro: JavaScript é muito mais leve para expressar funcionalidade. É difícil provar isso com palavras, mas JSON , digitação dinâmica, notação lambda, herança prototípica, módulos leves, o que seja ... tudo isso tende a levar menos código para expressar as mesmas idéias.
  • Con: Talvez você realmente goste de serviços de codificação em Java?

Para outra perspectiva sobre JavaScript e Node.js, confira De Java a Node.js , uma postagem no blog sobre as impressões e experiências de um desenvolvedor Java aprendendo o Node.js.


Módulos Ao considerar nó, tenha em mente que a sua escolha de bibliotecas JavaScript vai DEFINE sua experiência. A maioria das pessoas usa pelo menos dois, um auxiliar de padrão assíncrono (Step, Futures, Async) e um módulo de açúcar JavaScript ( Underscore.js ).

Auxiliar / JavaScript Sugar:

  • Underscore.js - use isso. Apenas faça. Isso torna seu código agradável e legível com coisas como _.isString () e _.isArray (). Não tenho muita certeza de como você poderia escrever um código seguro. Além disso, para obter uma linha de comando aprimorada fu, confira meu próprio Underscore-CLI .

Módulos de padrão assíncrono:

  • Etapa - uma maneira muito elegante de expressar combinações de ações seriais e paralelas. Minha recomendação pessoal. Veja minha postagem sobre como é o código da etapa.
  • Futuros - maneira muito mais flexível (isso é realmente uma coisa boa?) De expressar pedidos através de requisitos. Pode expressar coisas como "inicie a, b, c em paralelo. Quando A e B terminam, inicie AB. Quando A e C terminam, inicie AC". Essa flexibilidade requer mais cuidado para evitar erros no seu fluxo de trabalho (como nunca chamar o retorno de chamada ou chamá-lo várias vezes). Veja o post de Raynos sobre o uso de futuros (este é o post que me fez "obter" futuros).
  • Async - biblioteca mais tradicional com um método para cada padrão. Comecei com isso antes da minha conversão religiosa para a etapa e a subsequente percepção de que todos os padrões no Async podiam ser expressos na Etapa com um único paradigma mais legível.
  • TameJS - Escrito por OKCupid, é um pré-compilador que adiciona um novo idioma primitivo "aguardar" para escrever elegantemente fluxos de trabalho seriais e paralelos. O padrão parece incrível, mas requer pré-compilação. Eu ainda estou decidindo sobre isso.
  • StreamlineJS - concorrente do TameJS. Estou inclinado para Tame, mas você pode se decidir.

Ou para ler tudo sobre as bibliotecas assíncronas, consulte esta entrevista em painel com os autores.

Estrutura da Web:

  • Expresse o framework Great Ruby on Rails-esk para organizar sites. Ele usa o JADE como um mecanismo de modelagem XML / HTML, o que torna a construção do HTML muito menos dolorosa, quase elegante até.
  • jQuery Embora tecnicamente não seja um módulo de nó, o jQuery está rapidamente se tornando um padrão de fato para a interface do usuário do lado do cliente. O jQuery fornece seletores do tipo CSS para 'consultar' os conjuntos de elementos DOM que podem ser operados (manipuladores, propriedades, estilos, etc.). Na mesma linha, a estrutura CSS do Bootstrap do Twitter , o Backbone.js para um padrão MVC e o Browserify.js para agrupar todos os seus arquivos JavaScript em um único arquivo. Todos esses módulos estão se tornando padrões de fato; portanto, você deve pelo menos conferi-los se ainda não os ouviu.

Teste:

  • JSHint - deve usar; Eu não usei isso no começo, o que agora parece incompreensível. O JSLint adiciona de volta várias verificações básicas que você obtém com uma linguagem compilada como Java. Parênteses incompatíveis, variáveis ​​não declaradas, tipos de várias formas e tamanhos. Você também pode ativar várias formas do que chamo de "modo anal", onde verifica o estilo de espaço em branco e outros enfeites, o que é bom se essa é sua xícara de chá - mas o valor real vem da obtenção de feedback instantâneo sobre o número exato da linha em que você esqueceu um fechamento ")" ... sem precisar executar seu código e acessar a linha incorreta. "JSHint" é uma variante mais configurável de Douglas Crockford 's JSLint .
  • Mocha concorrente de votos que eu estou começando a preferir. Ambas as estruturas lidam bem com o básico, mas padrões complexos tendem a ser mais fáceis de expressar no Mocha.
  • Votos Votos é realmente bastante elegante. E ele imprime um relatório adorável (--spec) mostrando quais casos de teste foram aprovados / reprovados. Passe 30 minutos aprendendo e poderá criar testes básicos para seus módulos com o mínimo de esforço.
  • Zombie - Teste sem cabeça para HTML e JavaScript usando JSDom como um "navegador" virtual. Coisas muito poderosas. Combine-o com o Replay para obter testes determinísticos extremamente rápidos de código no navegador.
  • Um comentário sobre como "pensar em" testes:
    • O teste não é opcional. Com uma linguagem dinâmica como o JavaScript, há muito poucas verificações estáticas. Por exemplo, passar dois parâmetros para um método que espera 4 não será interrompido até que o código seja executado. Barra bastante baixa para criar bugs em JavaScript. Testes básicos são essenciais para preencher a lacuna de verificação com os idiomas compilados.
    • Esqueça a validação, basta executar seu código. Para todo método, meu primeiro caso de validação é "nada quebra", e é o caso que é acionado com mais frequência. Provar que seu código é executado sem gerar captura de 80% dos bugs e fará muito para melhorar sua confiança no código que você voltará e adicionará os casos de validação diferenciados que ignorou.
    • Comece pequeno e quebre a barreira inercial. Somos todos preguiçosos e pressionados pelo tempo, e é fácil ver os testes como "trabalho extra". Então comece pequeno. Escreva o caso de teste 0 - carregue seu módulo e relate o sucesso. Se você se esforçar para fazer exatamente isso, a barreira inercial ao teste será quebrada. São menos de 30 minutos para fazer isso pela primeira vez, incluindo a leitura da documentação. Agora escreva o caso de teste 1 - chame um de seus métodos e verifique "nada quebra", ou seja, se você não recebe um erro de volta. O caso de teste 1 deve levar menos de um minuto. Com a inércia perdida, torna-se fácil expandir gradualmente sua cobertura de teste.
    • Agora evolua seus testes com seu código. Não se intimide com a aparência do teste "correto" de ponta a ponta com servidores simulados e tudo mais. O código começa simples e evolui para lidar com novos casos; testes devem também. À medida que você adiciona novos casos e nova complexidade ao seu código, adicione casos de teste para exercitar o novo código. Ao encontrar erros, adicione verificações e / ou novos casos para cobrir o código defeituoso. Quando você estiver depurando e perder a confiança em um pedaço de código, volte e adicione testes para provar que está fazendo o que pensa. Capture seqüências de dados de exemplo (de outros serviços que você chama, sites que você raspa, o que for) e alimente-os com seu código de análise. Alguns casos aqui, validação aprimorada lá, e você terminará com um código altamente confiável.

Além disso, confira a lista oficial dos módulos Node.js. recomendados. No entanto, o Wiki de módulos de nós do GitHub é muito mais completo e um bom recurso.


Para entender o Node, é útil considerar algumas das principais opções de design:

O Node.js é BASEADO EM EVENTOS e ASSÍNCRONO / NÃO BLOQUEADO. Eventos, como uma conexão HTTP recebida, disparam uma função JavaScript que faz um pouco de trabalho e iniciam outras tarefas assíncronas, como conectar-se a um banco de dados ou extrair conteúdo de outro servidor. Depois que essas tarefas são iniciadas, a função de evento termina e o Node.js volta a dormir. Assim que outra coisa acontece, como a conexão do banco de dados sendo estabelecida ou o servidor externo respondendo ao conteúdo, as funções de retorno de chamada são acionadas e mais código JavaScript é executado, potencialmente iniciando ainda mais tarefas assíncronas (como uma consulta ao banco de dados). Dessa forma, o Node.js entrelaçará alegremente atividades para vários fluxos de trabalho paralelos, executando quaisquer atividades que sejam desbloqueadas a qualquer momento. É por isso que o Node.js faz um ótimo trabalho gerenciando milhares de conexões simultâneas.

Por que não usar apenas um processo / thread por conexão como todos os outros?No Node.js, uma nova conexão é apenas uma alocação de heap muito pequena. A ativação de um novo processo requer significativamente mais memória, um megabyte em algumas plataformas. Mas o custo real é a sobrecarga associada à alternância de contexto. Quando você tem 10 ^ 6 threads de kernel, o kernel precisa trabalhar bastante para descobrir quem deve executar a seguir. Um monte de trabalho foi dedicado à construção de um planejador O (1) para Linux, mas no final, é muito mais eficiente ter um único processo orientado a eventos do que 10 ^ 6 processos competindo pelo tempo da CPU. Além disso, sob condições de sobrecarga, o modelo de multiprocessos se comporta muito mal, passando por serviços críticos de administração e gerenciamento, especialmente SSHD (o que significa que você não pode nem entrar na caixa para descobrir como está realmente ferrado).

O Node.js é SINGLE THREADED e LOCK FREE . O Node.js, como uma opção de design muito deliberada, possui apenas um único encadeamento por processo. Por esse motivo, é fundamentalmente impossível que vários threads acessem dados simultaneamente. Portanto, nenhum bloqueio é necessário. Threads são difíceis. Realmente muito difícil. Se você não acredita nisso, não fez programação em threads suficiente. Acertar o bloqueio é difícil e resulta em erros realmente difíceis de rastrear. Eliminar bloqueios e multithreading faz com que uma das classes mais desagradáveis ​​de bugs desapareça. Essa pode ser a maior vantagem do nó.

Mas como aproveito minha caixa de 16 núcleos?

Dois caminhos:

  1. Para grandes tarefas de computação pesada, como codificação de imagens, o Node.js pode iniciar processos filho ou enviar mensagens para processos de trabalho adicionais. Nesse design, você teria um thread gerenciando o fluxo de eventos e N processos executando tarefas pesadas de computação e mastigando as outras 15 CPUs.
  2. Para dimensionar a taxa de transferência em um serviço da Web, você deve executar vários servidores Node.js. em uma caixa, uma por núcleo, usando cluster (com Node.js. v0.6.x, o módulo "cluster" oficial vinculado aqui substitui a versão learnboost que possui uma API diferente). Esses servidores locais do Node.js. podem competir em um soquete para aceitar novas conexões, equilibrando a carga entre eles. Depois que uma conexão é aceita, ela se torna fortemente vinculada a um único desses processos compartilhados. Em teoria, isso parece ruim, mas, na prática, funciona muito bem e permite evitar a dor de cabeça ao escrever códigos seguros para threads. Além disso, isso significa que o Node.js obtém excelente afinidade do cache da CPU, mais efetivamente usando a largura de banda da memória.

O Node.js permite que você faça coisas realmente poderosas sem suar a camisa. Suponha que você tenha um programa Node.js. que executa uma variedade de tarefas, ouve em umaporta TCP comandos, codifica algumas imagens, qualquer que seja. Com cinco linhas de código, você pode adicionar um portal de gerenciamento da Web baseado em HTTP que mostra o status atual das tarefas ativas. Isso é FÁCIL de fazer:

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(myJavascriptObject.getSomeStatusInfo());
}).listen(1337, "127.0.0.1");

Agora você pode acessar um URL e verificar o status do seu processo em execução. Adicione alguns botões e você terá um "portal de gerenciamento". Se você possui um script Perl / Python / Ruby em execução, apenas "inserir um portal de gerenciamento" não é exatamente simples.

Mas o JavaScript não é lento / ruim / mal / cria-do-diabo? O JavaScript tem algumas esquisitices estranhas, mas com "as partes boas" existe uma linguagem muito poderosa e, de qualquer forma, o JavaScript é a linguagem do cliente (navegador). O JavaScript está aqui para ficar; outros idiomas o visam como uma IL, e talentos de classe mundial estão competindo para produzir os mais avançados mecanismos JavaScript. Devido ao papel do JavaScript no navegador, uma enorme quantidade de esforço de engenharia está sendo lançada para tornar o JavaScript extremamente rápido. V8é o melhor e mais recente mecanismo javascript, pelo menos para este mês. Ele impressiona as outras linguagens de script em eficiência e estabilidade (olhando para você, Ruby). E isso só vai melhorar com grandes equipes trabalhando no problema da Microsoft, Google e Mozilla, competindo para criar o melhor mecanismo JavaScript (não é mais um "intérprete" JavaScript, pois todos os mecanismos modernos fazem toneladas de JITcompilando sob o capô com interpretação apenas como um substituto para o código de execução única). Sim, todos nós desejamos poder corrigir algumas das opções mais estranhas da linguagem JavaScript, mas não é tão ruim assim. E a linguagem é tão flexível que você realmente não está codificando JavaScript, está codificando Step ou jQuery - mais do que qualquer outra linguagem, em JavaScript, as bibliotecas definem a experiência. Para criar aplicativos da Web, você precisa conhecer o JavaScript de qualquer maneira, portanto, a codificação no servidor tem uma espécie de sinergia de conjunto de habilidades. Isso me fez não temer escrever código de cliente.

Além disso, se você realmente odeia JavaScript, pode usar açúcar sintático como o CoffeeScript . Ou qualquer outra coisa que crie código JavaScript, como o Google Web Toolkit (GWT).

Falando em JavaScript, o que é um "fechamento"? - Uma maneira bastante elegante de dizer que você retém variáveis ​​de escopo lexicamente nas cadeias de chamadas. ;) Como isso:

var myData = "foo";
database.connect( 'user:pass', function myCallback( result ) {
    database.query("SELECT * from Foo where id = " + myData);
} );
// Note that doSomethingElse() executes _BEFORE_ "database.query" which is inside a callback
doSomethingElse();

Veja como você pode simplesmente usar "myData" sem fazer nada de estranho, como esconder em um objeto? E, diferentemente do Java, a variável "myData" não precisa ser somente leitura. Esse poderoso recurso de linguagem torna a programação assíncrona muito menos detalhada e menos dolorosa.

Escrever código assíncrono sempre será mais complexo do que escrever um script simples de thread único, mas com o Node.js, não é muito mais difícil e você obtém muitos benefícios, além da eficiência e escalabilidade de milhares de conexões simultâneas. ..


"a variável 'myData' não precisa ser somente leitura" - parece que você deseja mantê-la imutável na maioria das vezes para evitar problemas de simultaneidade, certo?
20412 Nick

1
@ Nick - isso é falso. "problemas de simultaneidade" são atenuados pelo fato de o nó ser único encadeado. O bloqueio no nó simplesmente não existe; não é necessário em um paradigma de thread único.
Dave Dopson


1
ps, observação - na verdade, editei-o várias vezes para que o post se tornasse "wiki da comunidade" (o limite é de 10 edições). Eu pensei erroneamente que isso era algum tipo de honra, quando na verdade apenas bloqueia o ganho de reputação dos votos positivos. Eventualmente, um dos eleitores anteriores ao status da CW clicou em "não votar" (espero, por acidente :) e eu perdi a reputação ... confuso, arquivei meta.stackexchange.com/questions/129941/… e fui treinado em "Comunidade Wiki "na verdade significa. Os mods tiveram a gentileza de remover o status CW. :)
Dave Dopson

1
@ John - meu comentário de depuração se aplica absolutamente ao vanny asnyc também. Para interromper a depuração, tudo o que preciso fazer é quebrar alguma chamada de função em "process.nextTick (...)". Então, quando for lançado, meu rastreamento de pilha começará com process.nextTick; não é tão útil. O que realmente quero saber é: "que pilha agendou process.nextTick?" Eu chamo esses dados de "cadeias causais", e isso me lembra de 'causeBy' no tratamento de exceções Java ... Lances de código de baixo nível, o código de nível intermediário captura a exceção LL e lança FrameworkMethodFailedException - sem 'causeBy', a pilha do LL código seria perdido.
21812 Dave Dopson

85

V8 é uma implementação de JavaScript. Permite executar aplicativos JavaScript independentes (entre outras coisas).

O Node.js é simplesmente uma biblioteca escrita para a V8 que realiza E / S com eventos. Esse conceito é um pouco mais complicado de explicar, e tenho certeza que alguém responderá com uma explicação melhor do que eu ... O essencial é que, em vez de fazer alguma entrada ou saída e esperar que isso aconteça, você simplesmente não espera para terminar. Por exemplo, solicite a última hora editada de um arquivo:

// Pseudo code
stat( 'somefile' )

Isso pode levar alguns milissegundos ou segundos. Com a E / S registrada, você simplesmente dispara a solicitação e, em vez de esperar, anexa um retorno de chamada que é executado quando a solicitação é concluída:

// Pseudo code
stat( 'somefile', function( result ) {
  // Use the result here
} );
// ...more code here

Isso se parece muito com o código JavaScript no navegador (por exemplo, com a funcionalidade de estilo Ajax ).

Para mais informações, você deve conferir o artigo Node.js é realmente empolgante, que foi minha introdução à biblioteca / plataforma ... Eu achei muito bom.


4
Como as E / S de eventos são implementadas sem o uso de bloqueios, o uso de threads, processos e fechamentos? E sinto que os conceitos são bastante semelhantes aos da programação funcional e do Erlang.
10109 Jeff

1
É implementado como um loop de eventos simples, até onde eu sei. A v8 já possui a funcionalidade de retorno de chamada / etc, assim como qualquer implementação de javascript.
rfunduk 11/12/2009

2
O loop de eventos de E / S do node.js significa que, em qualquer ponto do tempo, no máximo, apenas uma coisa está sendo feita. Eu vejo dois ganhos significativos: não há sobrecarga na troca de encadeamentos, portanto o node.js é muito rápido e, em segundo lugar, muitos bugs de simultaneidade típicos que Java é notório, pois não são possíveis.
precisa saber é

1
"Como as E / S de eventos são implementadas sem usar ... fechamentos?" O JavaScript suporta fechamentos e eles são usados ​​o tempo todo no node.js (funções anônimas e exemplo aqui).
panzi

@panzi: Não percebeu que Jeffrey incluiu fechamentos em sua lista de coisas que o node.js é implementado 'sem'. Obviamente cada função em javascript é um fechamento em torno dele do âmbito :)
rfunduk

35

O Node.js é uma ferramenta de linha de comando de código aberto criada para o código JavaScript do servidor. Você pode baixar um tarball , compilar e instalar a fonte. Permite executar programas JavaScript.

O JavaScript é executado pelo V8 , um mecanismo JavaScript desenvolvido pelo Google, usado no navegador Chrome . Ele usa uma API JavaScript para acessar a rede e o sistema de arquivos.

É popular por seu desempenho e pela capacidade de executar operações paralelas.

Compreender o node.js é a melhor explicação do node.js que encontrei até agora.

A seguir estão alguns bons artigos sobre o assunto.


13

Os fechamentos são uma maneira de executar o código no contexto em que foi criado.

O que isso significa para concordância é que você pode definir variáveis, iniciar uma função de E / S sem bloqueio e enviar a ela uma função anônima para seu retorno de chamada.

Quando a tarefa estiver concluída, a função de retorno de chamada será executada no contexto com as variáveis, este é o fechamento.

O motivo pelo qual os fechamentos são tão bons para escrever aplicativos com E / S sem bloqueio é que é muito fácil gerenciar o contexto de funções executadas de forma assíncrona.


8

Dois bons exemplos são sobre como você gerencia modelos e usa aprimoramentos progressivos com ele. Você só precisa de algumas partes leves de código JavaScript para fazê-lo funcionar perfeitamente.

Eu recomendo fortemente que você assista e leia estes artigos:

Escolha qualquer idioma e tente se lembrar de como gerenciar seus modelos de arquivo HTML e o que você deve fazer para atualizar um único nome de classe CSS em sua estrutura DOM (por exemplo, um usuário clicou em um item de menu e você deseja que seja marcado como "selecionado" e atualize o conteúdo da página).

Com o Node.js, é tão simples quanto fazê-lo no código JavaScript do lado do cliente. Obtenha seu nó DOM e aplique sua classe CSS a isso. Obtenha seu nó DOM e internalHTML seu conteúdo (você precisará de algum código JavaScript adicional para fazer isso. Leia o artigo para saber mais).

Outro bom exemplo é que você pode tornar sua página da Web compatível com JavaScript ativado ou desativado com o mesmo trecho de código. Imagine que você tenha uma seleção de datas em JavaScript que permitiria que seus usuários selecionassem qualquer data usando um calendário. Você pode escrever (ou usar) o mesmo código JavaScript para fazê-lo funcionar com o JavaScript ativado ou desativado.


7

Existe uma analogia muito boa do local de fast food que melhor explica o modelo orientado a eventos do Node.js., consulte o artigo completo, Node.js., consultórios médicos e restaurantes de fast food - Compreendendo a programação orientada a eventos

Aqui está um resumo:

Se a lanchonete de fast food seguisse um modelo tradicional baseado em threads, você pedia sua comida e aguardava na fila até recebê-la. A pessoa atrás de você não poderá fazer o pedido até que seu pedido seja feito. Em um modelo orientado a eventos, você pede sua comida e sai da fila para esperar. Todo mundo está livre para fazer o pedido.

O Node.js é orientado a eventos, mas a maioria dos servidores Web é baseada em threads. O York explica como o Node.js funciona:

  • Você usa seu navegador da web para fazer uma solicitação para "/about.html" em um servidor da web Node.js.

  • O servidor Node.js. aceita sua solicitação e chama uma função para recuperar esse arquivo do disco.

  • Enquanto o servidor Node.js aguarda a recuperação do arquivo, ele atende à próxima solicitação da Web.

  • Quando o arquivo é recuperado, há uma função de retorno de chamada que é inserida na fila de servidores Node.js.

  • O servidor Node.js executa essa função que, nesse caso, renderiza a página "/about.html" e a envia de volta ao seu navegador da Web. "


6

Bem, eu entendo isso

  • O objetivo do nó é fornecer uma maneira fácil de criar programas de rede escaláveis.
  • O nó é similar no design e influenciado por sistemas como Ruby Event Machine ou Twisted do Python.
  • E / S de eventos para javascript V8.

Para mim, isso significa que você estava correto nas três suposições. A biblioteca parece promissora!


1
Muitas vezes, acho que a página é bastante vaga.
10119 Jeff

6

Além disso, não esqueça de mencionar que o V8 do Google é MUITO rápido. Na verdade, ele converte o código JavaScript em código de máquina com o desempenho correspondente do binário compilado. Então, junto com todas as outras grandes coisas, é incrivelmente rápido.


3

Q: O modelo de programação é orientado a eventos, especialmente a forma como ele lida com I / O .

Corrigir. Ele usa retornos de chamada, portanto, qualquer solicitação para acessar o sistema de arquivos faria com que uma solicitação fosse enviada ao sistema de arquivos e, em seguida, o Node.js começaria a processar sua próxima solicitação. Apenas se preocuparia com a solicitação de E / S quando receber uma resposta do sistema de arquivos, quando executará o código de retorno de chamada. No entanto, é possível fazer solicitações de E / S síncronas (ou seja, solicitações de bloqueio). Cabe ao desenvolvedor escolher entre assíncrono (retorno de chamada) ou síncrono (em espera).

P: Ele usa JavaScript e o analisador é V8.

sim

P: Pode ser facilmente usado para criar aplicativos de servidor simultâneos.

Sim, embora você precise codificar manualmente bastante JavaScript. Talvez seja melhor olhar para uma estrutura, como http://www.easynodejs.com/ - que vem com documentação on-line completa e um aplicativo de amostra.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.