一个Node.js初学者的“班门弄斧

凌晨三点,当启动控制台(console)的时候,手已经按在键盘上了。黑色背景上出现了扎眼的提示,渴求接收命令。想折腾下node.js?node,js有一个令人兴奋的消息:它可以在任何地方运行。这一点让栈有了多种不同的尝试方式。对任何一个经验丰富的人,使用命令行来运行都充满了乐趣。我最喜欢的是可以在命令行的安全网络中审阅栈。牛逼的是我们仍然在说javascript,所以你们中的大部分不会有任何问题。那么,为什么不开始在console里启动node呢?

本文中,我会向你介绍Node.js。我的目标是在一些有难度的地方能看下出彩的部分。本文是一篇概述留存在console里的栈的媒介。如果你想看看适合新手的Node.js指南,不妨看看SitePoint的优质课程Node.js:An Introduction.

为什么是Node.js?

在我们开始前,先看看让Node.js鹤立鸡群的”花边“新闻:

  • 为非阻塞I/O而设计
  • 为异步操作而设计
  • 驱动Chrome的V8 JavaScript

你可能已经从很多地方知道以上几点了,但是这些到底是什么意思呢?你可以将Node.js看作是一个为javascript提供了大量API的引擎。在传统的同步编程方式中,当你有一个I/O操作时,API在运行下一条指令前会处于等待状态。I/O操作就是,举个例子,读取文件或发出一个网络请求。Node.js不同,它从设计之初就是为了异步操作。在当下的编程环境,这一点有巨大的优势。你还能想起你最后一次因为一个更快的单核处理器而换电脑是什么时候吗?处理器的数量和更快的硬盘更加重要。

接下来的文章中,当你看到>这个提示标志时,意味着需要按enter并输入下一条指令。此外,在运行本文中的代码时,你需要开启CLI,并执行指令node(注:需要先下载并安装node.js),说着就开始吧!

回调(Callbacks)

首先输入下列函数:

  1. >function add(a,b,callback){var result = a+b;callback(result);}

对网络新手,JavaScript中的callback可能很陌生。这看起来并不是一个典型的OOP方法。在JavaScript中,函数(function)是一个对象,对象可以接受其它对象作为参数。JavaScript并不在乎对象是什么,所以一个函数可以接受另一个是函数的对象。数字参数数量,在回调函数中通过add()由两个变为一个。回调系统相当的强大,因为它支持封装并将现实封装隐藏。在Node.js中,你会发现有许多APIs将一个回调作为参数。可以把回调想象成是一个代表。程序隐藏在里面,而这个代表就是经授权被派遣代替别人的人。所以回调像是派一个人来完成差事。给一系列参数,就像列出一个购物单,然后他们就自己去完成任务了。

为了玩转add():

  1. > add(2, 3, function (c) { console.log(‘2 + 3 = ‘ + c) });
  2. > add(1, 1, function (c) { console.log(‘Is 1 + 1 = 3? ‘ + (c === 3)); });

多尝试一些回调的新奇玩法吧。它是Node.js中一些重要API的基础。

异步操作

通过回调,我们可以开始编写一些异步API了,举个栗子(其实这个季节似乎没有栗子可以举):

  1. > function doSomething (asyncCallback) { asyncCallback(); }
  2. > doSomething(function () { console.log(‘This runs synchronously.‘); });

这个特例中有一个同步操作,但是对于JavaScript中的异步操作,我们已经万事俱备了。asyncCallback,可以在一些线程中被延迟:

  1. > function doSomething (asyncCallback) { setTimeout(asyncCallback, Math.random() + 1000); }
  2. > doSomething(function () { console.log(‘This runs asynchronously.‘); }); console.log(‘test‘);

我用了setTimeout在当前线程中延迟操作。timeout并没有给定时间,所以我使用Math.random()来设一个变化的时间。取名为doSomething,然后用console.log(‘test’)来显示被延后的操作。在1~2秒钟后,就可以在屏幕上看懂啊弹出的消息了。我举例的异步回调是不可预测的。Node.js将其放在时间表里,继续前面的进程。时间到了后,Node,js刚好运行到这个异步操作的时间,然后调用这个回调。所以你必须脑中明晰各种回调以更好的理解Node.js。

一句话,在JavaScript中,回调并不总是它看起来的样子。

让我们做一些更有趣的事(原谅我没发现哪里有趣)。不如试试在Node.js中查找DNS?

  1. > dns.lookup(‘bing.com‘, function (err, address, family) { console.log(‘ Address: ‘ + address + ‘, Family: ‘ + family + ‘, Err: ‘ + err); });

这个回调返回err,address,family三个对象,重点是返回值被当作参数传递给回调。所以这个传统的像var result= fn(‘bing.com‘)不太一样。在Node.js中,必须通过回调和异步来获得总体概况。你可以去看看[DNS Node.js API][2]了解更多细节。下图是我控制台里DNS lookup的样子:

文件I/O

现在继续,在Node,js中怎么执行文件写入写出呢?想象这个场景:你打开一个文件,读取文件内容然后写入新的内容。在现代工艺的电脑上I/O-bound(天,我完全不知道这怎么翻译,知道的私信我,我改)操作很慢。CPU处理速度很快,RAM也很快。但是,硬盘的读取或写入速度很慢。因此当程序同步执行I/O-bound操作时,运行的很慢。替代方法是采用异步,比如:

  1. > var fs = require(‘fs‘);
  2. > fs.writeFile(‘message.txt‘, ‘Hello Node.js‘, function () { console.log(‘Saved.‘); }); console.log(‘Writing file...‘);

因为操作是异步的,因此你会先看到“writing file...."然后看到文件被保存。回调函数最普通的使用方式十分适合这个API。你可以看看文档[file System API][6]这部分。读取文件又是怎样做呢?你能通过前例猜猜么?给你一点小提示,回调参数是err和data.我建议你试试。

答案:

  1. > fs.readFile(‘message.txt‘, function(err, data) { console.log(data); });

你也可以传入一个encoding项来读取文件中utf-8内容:

  1. > fs.readFile(‘message.txt‘, {encoding: ‘utf-8‘}, function(err, data) { console.log(data); });

Node.js回调函数的异步I/O操作看起来很完美。

Web 服务器

那么在Web服务器上会怎样呢?任何一个优秀的Exposé(MacOS上的多窗口管理工具?)都必须运行一个Web服务端。假设有一个叫做creatServer的API,这个API有一个参数是request和response的回调。你可以在文档中看看HTTP API。你能想到是什么样子吗?你需要Http模块。去console里试试吧。

答案:

  1. > var http = require(‘http‘);
  2. > var server = http.createServer(function (request, response) { response.end(‘Hello Node.js‘); });

细想一下web,它是一个带有请求和响应模块的客户端-服务器。Node.js有一个来自客户端的request对象和一个来自服务器的response对象。因此栈通过简单的回调原理解决web难题。还记得它是异步的吗?我希望你能把零散的回忆综合一下,如果你看了API文档,我们现在做的很那个差不多。我们载入一个模块,告诉它要做什么并给它一个参数。回调就会像一个代表那样工作:执行一个有一系列参数的特殊任务。

当然,如果我们不能在浏览器中看到它,那么一切都是无意义的。在CLI中添加:

  1. server.listen(8080);

然后将你最爱的浏览器指定为:localhost:8080,我用的是Edge。

假设requset对象有一堆可获取的信息。为了重新连上server,先将其关闭(bring it down):

  1. > server.close();
  2. > server = http.createServer(function (request, response) { response.end(request.headers[‘user-agent‘]); }); server.listen(8081);

将浏览器指定为:localhost:8081.header提供给你来自浏览器的user-agent信息。我们可以遍历header对象:

  1. > server.close();
  2. > server = http.createServer(function (request, response) { Object.keys(request.headers).forEach(function (key) { response.write(key + ‘: ‘ + request.headers[key] + ‘ ‘); }); response.end(); }); server.listen(8082);

这次 将浏览器指定为:localhost:8082。一旦完成之后,记得关闭。否则命令行可能会产生奇怪的运行结果。

  1. > server.close();

你已经学会啦,通过命令行来创建web服务器。我希望你喜欢这趟node迷幻之旅。

总结

Node.js很适合现代的解决方案,因为其十分简单而轻便。它充分利用了现代硬件非模块设计的优点。它包含了web固有的客户端-服务器模块。最好都用我们喜欢的JavaScript运行。引起我兴趣的是栈的关键部分并不前沿。网页来自早期构建的轻量级易接入模块。如果有时间,我建议你看看Tim Berners-Lees’ Design Principles.。原则中为Node.js的least power applies提供了JavaScript选项。

原文链接:http://www.gbtags.com/gb/share/9522.htm

时间: 2024-10-05 08:13:05

一个Node.js初学者的“班门弄斧的相关文章

编写第一个node.js应用

step1:引入 required 模块 首先使用 require 指令来载入 http 模块,并将实例化的 HTTP 赋值给变量 http,实例如下: step2:创建服务器 接下来使用 http.createServer() 方法创建服务器,并使用 listen 方法绑定 8888 端口. 函数通过 request, response 参数来接收和响应数据. 实例如下,创建一个叫 server.js 的文件,并写入以下代码: step3:接收请求与响应请求  以上代码完成了一个可以工作的 H

Node.js源码解析----自己实现一个Node.js的难点与思路

前言: 最近在看Node.js,看了一段时间后便想着自己实现一个Node.js现在已经实现了个大概(绝大部分是模仿人家,不过自己实现一遍基本上就理解Node.js的原理了)下面便说说这个过程中的坑,以及一些需要注意的地方: Node.js需要一定C++基础,建议看完C++Primer再看,否则V8的好多表达方式,指针,引用,模板之类的会看不懂: 代码已上传GitHub地址:   https://github.com/sven36/cNode 编译:我用的win10的环境,具体编译请参考Node.

第一个Node.js应用

创建Node.js应用前,我们要知道Node.js是分模块的,其中 "http模块" 是其内置模块可以直接使用(先这么记着就行,不需要深究,以后就明白了). 新建一server.js文件,其内容为: // 请求 http模块 获得访问网络的能力 var http = require('http') ; http.createServer(function(request , response){ // 发送 HTTP 头部 // HTTP 状态值:200 :OK // 内容类型:tex

node.js教程基础:第一个node.js程序

第一个Node.js程序 可以是基于控制台console和基于Web的node.js应用程序. 基于console的node.js例子 文件:console_example1.js 1 console.log('Hello World); 打开Node.js命令提示符并运行以下代码: >node console_example1.js >Hello World 在这里,console.log()函数在控制台上显示消息. 我们还可以在console.log()函数中使用格式说明符: 1 cons

【Node.js 学习一】 第一个Node.js应用--Hello World!

当我们使用PHP来编写后台代码时,需要使用Apache或者Nginx的HTTP服务器,并配上mod_php5模块和php-cgi. 从这个角度看,整个“接收HTTP请求并提供Web页面”的需求根本不需要PHP来处理. 不过对Node.js来说,概念完全不一样了.使用Node.js时,我们不仅仅在实现一个应用,同时还实现了整个HTTP服务器.事实上,我们的Web应用以及对应的Web服务器基本上是一样的. 在创建一个“Hello World”应用钱,让我们先了解一下Node.js的应用是由哪几部分组

开启第一个Node.js的Express项目

手动创建一个Express.js的应用可大致分为以下步骤: 1.创建文件夹 a. 创建一个项目根文件夹,如helloWord b.在项目的根目录下创建项目的目录结构,依次创建{public,public/css,public/img,public/js,db,views,views/includes,routes} 可使用命令: mkdir {public,public/css,public/img,public/js,db,views,views/includes,routes} 2.NPM初

Vue.js实践:一个Node.js+mongoDB+Vue.js的博客内容管理系统

项目来源 以前曾用过WordPress搭建自己的博客网站,但感觉WordPress很是臃肿.所以一直想自己写一个博客内容管理器. 正好近日看完了Vue各个插件的文档,就用着Vue尝试写了这个简约的博客内容管理器(CMS). 嗯,我想完成的功能: 一个基本的博客内容管理器功能,如后台登陆,发布并管理文章等 支持markdown语法实时编辑 支持代码高亮 管理博客页面的链接 博客页面对移动端适配优化 账户管理(修改密码) Demo 登陆后台按钮在页面最下方"站长登陆",可以以游客身份登入后

前端开发写一个node.js接口

本文章参考并实践这篇文章-----https://www.jianshu.com/p/20c4d72fb700 别看步骤多,但是非常简单非常简单的 第一步:安装node.js 首先要安装node,既然你都是前端了,这个环境肯定是有的 官网地址 https://nodejs.org/en/ 安装之后用node -v看看成功了没 第二步:创建一个文件,名字叫做se吧,进入文件之后npm init来创建一个package.json我的文件,init的过程你都按enter键就好了 第三步: 安装expr

例子:使用Grunt创建一个Node.js类库

? 创建一个文件夹. 打开命令行或者powershell, 运行npm init,根据提示填入package的信息. 在文件夹中创建index.js文件. /*! * mymongolib * Copyright(c) 2009-2013 Blabla * MIT Licensed */ ? 'use strict'; ? module.exports = require('./lib/mymongolib'); ? 在文件夹中创建lib目录,然后在新目录中创建mymongolib.js文件.