zoukankan      html  css  js  c++  java
  • 重拾nodeJs

    不确定为什么要去,正是出发的理由。

    Node.js 工作原理

    Node.js 的主要思路是:使用非阻塞的,事件驱动的 I/O (输入/输出端口)操作来保持在处理跨平台 (across distributed devices) 数据密集型实时应用时的轻巧高效。

    Node 真正的亮点在于建设高性能,高扩展性的互联网应用——因为它能够处理庞大的并且高并发的连接。

    总结:Node是一个可以让JavaScript运行在服务器端的平台,抛弃了传统平台依靠多线程来实现高并发的设计思路,而采用单线程、异步式I/O、事件驱动式的程序设计模型

    工作原理对比:

    传统的网络服务技术:每个新增一个连接(请求)便生成一个新的线程,这个新的线程会占用系统内存,最终会占掉所有的可用内存。

    Node.js :仅仅只运行在一个单线程中,使用非阻塞的异步 I/O 调用,所有连接都由该线程处理,在 libuv 的加分下,可以允许其支持数万并发连接(全部挂在该线程的事件循环中)。

    适用类型:

    Node.js 从来不是用于解决大规模计算问题而创建的。它的出现是为了解决大规模I/O 的问题,并且在这一点上做的非常好。

    如果项目需求中不包含CPU密集型操作,也不需要访问任何阻塞的资源,那么就可以利用的 Node.js 的优点,尽情的享受快速、可扩展的网络应用。

    Node.js快速入门 —— 异步式I/O与事件式编程

    回调函数

    异步式I/O是通过回调函数来实现的

    //用异步的方式读取一个文本内容为“Hello world”的文件fs
    var
    fs = require("fs");
    fs.readFile("test.txt", "utf-8", function(err, data) { console.log(data); });
    console.log("end");
    //运行结果
    Hello world
    end

    同步的方式是阻塞线程等待文件读取完毕后,将文件内容输出,然后才继续执行下一步代码,因此控制台先打印“Hello world”,然后再打印“end”。

    而异步式I/O是通过回调函数来实现的,通过将控制台输出文件内容的函数作为参数传给fs.readFile函数,fs.readFile调用时只是将异步式I/O请求发送给操作系统,然后立即返回并执行后面的语句,当fs接收到I/O请求完成的事件时,才会调用回调函数。因此我们先看到“end”,再看到“Hello world”的内容。

    事件

    Node.js所有的异步I/O操作在完成时都会发送一个事件到事件队列。事件由EventEmitter提供,前面提到的fs.readFile的回调函数就是通过EventEmitter来实现。

    模块和包

    Node提供了require函数来调用其他模块。node中的模块和包并没有本质的区别,包可以理解为某个功能模块的集合。

    什么是模块

    模块是node应用程序的基本组成部分,文件和模块是一一对应的。一个node.js文件就是一个模块,这个文件可能是JavaScript代码、JSON或者编译过的C/C++扩展。

    创建及加载模块

    node提供了exports和require两个对象,其中exports是模块的公开接口,require用于从外部获取一个模块的接口。

    新建一个myModule.js文件,输入如下代码:

    var text;
    
    function setText(myText){
        text = myText;
    }
    
    function printText(){
        console.log(text);
    }
    
    exports.setText = setText;
    exports.printText = printText;

    再新建一个test.js文件: 

    var myModule = require("./myModule");
    
    myModule.setText("Hello world!");
    myModule.printText();
    
    //运行test.js,结果为: Hello world
    !

    单次加载

    模块的调用与创建一个对象不同,require不会重复加载模块。

    修改test.js:

    var myModule1 = require("./myModule");
    myModule1.setText("Hello world!");
    
    var myModule2 = require("./myModule");
    myModule2.setText("Hi baby!");
    
    myModule1.printText();
    myModule2.printText();
    
    //运行结果: Hi bayby
    ! Hi bayby!

     这是因为模块不会重复加载,myModule1和myModule2指向的都是同一个实例,因此myModule1的text值就被myModule2覆盖了。

    exports.hello = function(){
        console.log("Hello world");
    };

    创建包

    包是模块基础上更深一步的抽象,类似于C/C++的函数库或者java/.net的类库。

    node包是一个目录,其中包括一个JSON格式的包说明文件package.json。node对包的要求并不严格,但还是建议制作包时遵循CommonJS规范。

    建立一个名为mypackage的文件夹,在文件夹中新建index.js:

    exports.hello = function(){ console.log("Hello world"); };

     然后在mypackage之外建立test.js:

    var mypackage = require("./mypackage");
    
    mypackage.hello();

    这就是一个简单的包了,通过定制package.json,我们可以创建更复杂的包。

    定制package.json:

    1. 在mypackage文件夹下创建一个package.json文件和一个lib子文件夹。
    2. 将index.js重命名为interface.js并放入lib文件夹。
    3. 打开package.json并输入如下json文本:

      {
      "main": "./lib/interface.js"
      }

    运行test.js,依然可以看到控制台输出“Hello world”。

    node调用某个包时,会首先检查package.json文件的main字段,将其作为包的接口模块,如果package.json或main字段不存在,就会去寻找index.js或index.node作为包的接口。

    node.js包管理器

    本地模式和全局模式

    npm默认为本地模式,会从http://npmjs.org搜索或下载包 ,将包安装到当前目录的node_modules
    子目录下。

    也可以使用全局安装,它会将包安装在系统目录:

    “npm [install/i] -g [package_name]”

    本地模式可以直接通过require使用,但是不会注册环境变量。
    全局模式不能直接通过require使用,但是它会注册环境变量。

    通过npm link命令可以在本地包和全局包之间创建符号链接,使全局包可以通过require使用,例如要require全局模式安装的express,可以在工程目录下运行:

    npm link express

    使用npm link命令还可以将本地包链接到全局,但是npm link命令不支持windows

    调试

    命令行调试

    例如要调试test.js,则在命令行中输入:

    node debug test.js

    以下为基本的调试命令:

    run: 执行脚本,在第一行暂停
    restart: 重新执行脚本
    cont, c: 继续执行,直到遇到下一个断点
    next, n: 单步执行
    step, s: 单步执行并进入函数
    out, o: 从函数中步出
    setBreakpoint(), sb(): 在当前行设置断点
    setBreakpoint(‘f()’), sb(...): 在函数f的第一行设置断点
    setBreakpoint(‘script.js’, 20), sb(...): 在 script.js 的第20行设置断点
    clearBreakpoint, cb(...): 清除所有断点
    backtrace, bt: 显示当前的调用栈
    list(5): 显示当前执行到的前后5行代码
    watch(expr): 把表达式 expr 加入监视列表
    unwatch(expr): 把表达式 expr 从监视列表移除
    watchers: 显示监视列表中所有的表达式和值
    repl: 在当前上下文打开即时求值环境
    kill: 终止当前执行的脚本
    scripts: 显示当前已加载的所有脚本
    version: 显示 V8 的版本

    远程调试

    使用以下语句之一可以打开调试服务器:

    node --debug[=port] test.js //脚本正常执行,调试客户端可以连接到调试服务器。
    node --debug-brk[=port] test.js //脚本暂停执行等待客户端连接。
    //如不指定端口,则默认为5858。
    
    //客户端:
    
    node debug 127.0.0.1:5858
    node-inspector
    
    //安装node-inspector:
    
    npm install -g node-inspector
    //在终端连接调试服务器:
    
    node --debug-brk=5858 test.js
    //启动node-inspector:
    
    node-inspector
    //在浏览器中打开http://127.0.0.1:8080/debug?port=5858。

     未完待续。。。。。。

  • 相关阅读:
    【Android Developers Training】 73. 布局变化的动画
    【Android Developers Training】 72. 缩放一个视图
    【Android Developers Training】 71. 显示翻牌动画
    svn更改地址怎么办
    python学习手册
    failed to bind pixmap to texture
    Ubuntu 12.04安装Google Chrome
    svn update 时总是提示 Password for '默认密钥' GNOME keyring: 输入密码
    重设SVN 的GNOME keyring [(null)] 的密码
    Nginx + uWSGI + web.py 搭建示例
  • 原文地址:https://www.cnblogs.com/shanhaihong/p/7490975.html
Copyright © 2011-2022 走看看