SlideShare a Scribd company logo
1 of 35
Download to read offline
Node.js 开发体验



           by QLeelulu
编程思想的改变
//node.js
                               var data;
//传统代码                         fs.readFile('file.txt',
var file = open('file.txt');      function(err, data){
var data = file.read();             data = data;
doSomething(data);                }
                               );
                               doSomething(data);
异步与回调
可读性
//传统的代码
var user = db.user.get('name');
var post = db.post.get(user.id);
var tags = db.tags.get(post.id);

              //异步回调方式
              db.user.get('name', function(err, user){
                  if(err) throw err;
                  db.post.get(user.id, function(err, post){
                      if(err) throw err;
                      db.tags.get(post.id, function(err, tags){
                          if(err) throw err;
                          //doWithResults();
                      });
                  });
              });
//传统代码
var value = Memcache.get('key');
if(!value){
   value = db.get('key');
   Memcache.set('key', value);
}
// 对value进行处理
                           //异步回调方式
                           function doWithValue(value){
                               // 对value进行处理
                           }
                           Memcache.get('key', function(err, value){
                               if(value){
                                  doWithValue(value);
                               }else{
                                  db.get('key', function(err, value){
                                      Memcache.set('key', value);
                                      doWithValue(value);
                                  });
                               }
                           });
原来流程清晰的代码,
可读性差了,
流程看起来也有点乱了
解决方案
●   封装代码
●   “ 编译”
    ●   https://github.com/Sage/streamlinejs

●   辅助函数
    ●   https://github.com/willconant/flow-js
    ●   http://howtonode.org/step-of-conductor
flow.exec(                         Flow-js 示例代码
     function() {
         fs.rename("/tmp/hello", "/tmp/world", this);
     },function(err) {
         if (err) throw err;
         fs.stat("/tmp/world", this)
     },function(err, stats) {
         if (err) throw err;
         sys.puts("stats: " + JSON.stringify(stats));
     }
);
                               其实吧,只是权宜之计~
更多 Flow control / Async goodies




https://github.com/joyent/node/wiki/modules#async-flow
Coroutine( 协程 )?

Cooperative threading of any sort is a bad idea.
                                     --ry@jsconf2010




     ●
      讨论:
         ●
           http://shiningray.cn/node-js-coroutine.html
         ●
           http://news.ycombinator.com/item?id=1549168
并行
博客首页:
var data = {};
// 获取最新10篇博客文章
db.getPosts(10, function(err, posts){
    data.posts = posts;
});
// 获取最新10条评论
db.getComments(10, function(err, comments){
    data.comments = comments;
});
// 获取Tags列表
db.getTags(function(err, tags){
    data.tags = tags;
});
// view.render(data);
                      注: db 的方法都为异步操作
并行获取数据很好很强大,
可是,
怎么知道全部数据都获取完了呢?
function Combo(callback) {
  this.callback = callback;
  this.items = 0;
}
Combo.prototype = {
  add: function () {
    this.items++;
  },
  finishOne: function () {
    this.items--;
    this.check();
  },
  check: function(){
     if (this.items == 0) {
       this.callback.apply(this);
     }

};
  }                                   并行辅助函数
                                    改自: http://howtonode.org/control-flow
var data = {};
var combo = new Combo(function(){
    view.render(data);
});                          最终回调
// 获取最新10篇博客文章
combo.add();
db.getPosts(10, function(err, posts){
    data.posts = posts;
    combo.finishOne();
});
// 获取最新10条评论
combo.add();
db.getComments(10, function(err, comments){
    data.comments = comments;
    combo.finishOne();
});
// ….
                              Combo 示例代码
Google V8 与 单线程
线程模型



                主线程




●
  主线程从左到右同时表示时间线      红色线代表的异步操作返回
●
  旁边的箭头代表异步操作         时,会发生什么情况呢?
●
  主线程上的色块代表异步操作返回后,
  执行代码所需的时间
var t;
function loop(){
    t = Date.now();
    for(var i=0; i< 10000*100000; i++){
        //console.log(i);
    }
};

function hello(){
    console.log((Date.now() - t) + 'ms');
};

setTimeout(loop, 100);
setTimeout(hello, 100);
●   主线程代码同步串行执行
●   同一时间只有一个回调函数在执行
●   异步回调会放到主线程的执行队列中,
    如果主线程正在执行其他代码,则等待
    调度,否则马上执行
高并发环境下呢?
var http = require('http');
http.createServer(function (req, res) {
   for(var i=0; i < 100*100000; i++){ }
   res.writeHead(200);
   res.end('Hello World');
}).listen(8080, "127.0.0.1");
Web Worker
●   耗 CPU 的操作放到 worker 中,
    不阻塞主进程
●   多 CPU 支持
●   目前 Node.js 还不支持 Web Worker
    ●
        In future versions, Node will be able to fork new
        processes (using the Web Workers API ) which
        fits well into the current design. – nodejs.org
    ●   https://github.com/pgriess/node-webworker
异常处理
var fs = require('fs');
try{
  fs.readFile('noFile',
     function(err, data){    如果异步回
       if (err) throw err;   调中抛出异
       console.log(data);    常会?
     }
  );
}catch(e){
  console.log('error');
}
异步回调函数外部 ,
无法捕获到异步回调函数内部的异常
process.on('uncaughtException', fn)

  可以捕获到任何未捕获的异常



      可是,
      没有了上下文变量
process.on('uncaughtException', function (err) {
    log(err);
});
http.createServer(function(req, res){
    try {
      mvcHandler(req, res);
    }                          如果此函数内部
    catch(e){                  有异步回调函数
      res.writeHead(200);      中抛出异常,客
      res.end('Server Error'); 户端则会得不到
    }                          响应
}).listen(8080, "127.0.0.1");
Express 中也存在该问题,
如果你有解决方案,
欢迎与我交流
调试




●   http://cnodejs.org/blog/?p=911
ECMAScript 5
●   Array
    ●   indexOf(), lastIndexOf(),
    ●   forEach(), map(), reduce(), filter(),
        every(), some()
●   JSON
    ●   JSON.parse(), JSON.stringify()
●   Object.keys()
●   Date.parse(), Date.now()
●   __defineGetter__, __defineSetter__
●
    更多 :http://davidflanagan.com/Talks/es5/slides.html
生产环境中,
怎样保证服务始终运行着?
Forever

●   确保脚本在持续运行着
●   Github: https://github.com/indexzero/forever
●   [sudo] npm install forever -g
●   forever start run.js
THX


Q&A
联系我
●

●
  http://qleelulu.cnblogs.com
●
  http:// 微博平台 /qleelulu
●
  qleelulu#gmail.com

More Related Content

What's hot

改善程序设计技术的50个有效做法
改善程序设计技术的50个有效做法改善程序设计技术的50个有效做法
改善程序设计技术的50个有效做法
crasysatan
 
LazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHPLazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHP
Lin Yo-An
 
JavaScript现代化排错实践
JavaScript现代化排错实践JavaScript现代化排错实践
JavaScript现代化排错实践
jeffz
 
.Net 技術研討(linq與架構開發)
.Net 技術研討(linq與架構開發).Net 技術研討(linq與架構開發)
.Net 技術研討(linq與架構開發)
Gelis Wu
 
深入剖析Concurrent hashmap中的同步机制(上)
深入剖析Concurrent hashmap中的同步机制(上)深入剖析Concurrent hashmap中的同步机制(上)
深入剖析Concurrent hashmap中的同步机制(上)
wang hongjiang
 
Wind.js无障碍调试与排错
Wind.js无障碍调试与排错Wind.js无障碍调试与排错
Wind.js无障碍调试与排错
jeffz
 

What's hot (20)

改善程序设计技术的50个有效做法
改善程序设计技术的50个有效做法改善程序设计技术的50个有效做法
改善程序设计技术的50个有效做法
 
LazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHPLazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHP
 
Golangintro
GolangintroGolangintro
Golangintro
 
JavaScript现代化排错实践
JavaScript现代化排错实践JavaScript现代化排错实践
JavaScript现代化排错实践
 
页游开发中的 Python 组件与模式
页游开发中的 Python 组件与模式页游开发中的 Python 组件与模式
页游开发中的 Python 组件与模式
 
JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1JavaScript 快速複習 2017Q1
JavaScript 快速複習 2017Q1
 
Glider
GliderGlider
Glider
 
论 Python 与设计模式。
论 Python 与设计模式。论 Python 与设计模式。
论 Python 与设计模式。
 
OpenResty 项目模块化最佳实践
OpenResty 项目模块化最佳实践OpenResty 项目模块化最佳实践
OpenResty 项目模块化最佳实践
 
Python 于 webgame 的应用
Python 于 webgame 的应用Python 于 webgame 的应用
Python 于 webgame 的应用
 
Golang server design pattern
Golang server design patternGolang server design pattern
Golang server design pattern
 
Mysql展示功能与源码对应
Mysql展示功能与源码对应Mysql展示功能与源码对应
Mysql展示功能与源码对应
 
Python xmlrpc-odoo
Python xmlrpc-odooPython xmlrpc-odoo
Python xmlrpc-odoo
 
.Net 技術研討(linq與架構開發)
.Net 技術研討(linq與架構開發).Net 技術研討(linq與架構開發)
.Net 技術研討(linq與架構開發)
 
BASH 漏洞深入探討
BASH 漏洞深入探討BASH 漏洞深入探討
BASH 漏洞深入探討
 
Lua 语言介绍
Lua 语言介绍Lua 语言介绍
Lua 语言介绍
 
Effective linux.1.(commandline)
Effective linux.1.(commandline)Effective linux.1.(commandline)
Effective linux.1.(commandline)
 
深入剖析Concurrent hashmap中的同步机制(上)
深入剖析Concurrent hashmap中的同步机制(上)深入剖析Concurrent hashmap中的同步机制(上)
深入剖析Concurrent hashmap中的同步机制(上)
 
Wind.js无障碍调试与排错
Wind.js无障碍调试与排错Wind.js无障碍调试与排错
Wind.js无障碍调试与排错
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closures
 

Similar to Node.js开发体验

D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版
Jackson Tian
 
Node.js在淘宝的应用实践
Node.js在淘宝的应用实践Node.js在淘宝的应用实践
Node.js在淘宝的应用实践
taobao.com
 
钟志 第八期Web标准化交流会
钟志 第八期Web标准化交流会钟志 第八期Web标准化交流会
钟志 第八期Web标准化交流会
Zhi Zhong
 
Javascript autoload
Javascript autoloadJavascript autoload
Javascript autoload
jay li
 
Erlang Practice
Erlang PracticeErlang Practice
Erlang Practice
litaocheng
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识
yiditushe
 
The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)
jeffz
 
Discuz技术交流
Discuz技术交流Discuz技术交流
Discuz技术交流
pigso
 

Similar to Node.js开发体验 (20)

D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版
 
Node.js在淘宝的应用实践
Node.js在淘宝的应用实践Node.js在淘宝的应用实践
Node.js在淘宝的应用实践
 
nodejs开发web站点
nodejs开发web站点nodejs开发web站点
nodejs开发web站点
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事
 
前端测试
前端测试前端测试
前端测试
 
前端测试
前端测试前端测试
前端测试
 
Hadoop Map Reduce 程式設計
Hadoop Map Reduce 程式設計Hadoop Map Reduce 程式設計
Hadoop Map Reduce 程式設計
 
钟志 第八期Web标准化交流会
钟志 第八期Web标准化交流会钟志 第八期Web标准化交流会
钟志 第八期Web标准化交流会
 
Browser vs. Node.js Jackson Tian Shanghai
Browser vs. Node.js   Jackson Tian ShanghaiBrowser vs. Node.js   Jackson Tian Shanghai
Browser vs. Node.js Jackson Tian Shanghai
 
PHP & MySQL 教學
PHP & MySQL 教學PHP & MySQL 教學
PHP & MySQL 教學
 
JavaScript Advanced Skill
JavaScript Advanced SkillJavaScript Advanced Skill
JavaScript Advanced Skill
 
Mvc
MvcMvc
Mvc
 
Javascript autoload
Javascript autoloadJavascript autoload
Javascript autoload
 
Erlang Practice
Erlang PracticeErlang Practice
Erlang Practice
 
从问题开始,谈前端架构
从问题开始,谈前端架构从问题开始,谈前端架构
从问题开始,谈前端架构
 
Asp.net mvc 培训
Asp.net mvc 培训Asp.net mvc 培训
Asp.net mvc 培训
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识
 
The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)
 
Discuz技术交流
Discuz技术交流Discuz技术交流
Discuz技术交流
 
Php
PhpPhp
Php
 

Node.js开发体验

  • 1. Node.js 开发体验 by QLeelulu
  • 3. //node.js var data; //传统代码 fs.readFile('file.txt', var file = open('file.txt'); function(err, data){ var data = file.read(); data = data; doSomething(data); } ); doSomething(data);
  • 5. 可读性 //传统的代码 var user = db.user.get('name'); var post = db.post.get(user.id); var tags = db.tags.get(post.id); //异步回调方式 db.user.get('name', function(err, user){ if(err) throw err; db.post.get(user.id, function(err, post){ if(err) throw err; db.tags.get(post.id, function(err, tags){ if(err) throw err; //doWithResults(); }); }); });
  • 6. //传统代码 var value = Memcache.get('key'); if(!value){ value = db.get('key'); Memcache.set('key', value); } // 对value进行处理 //异步回调方式 function doWithValue(value){ // 对value进行处理 } Memcache.get('key', function(err, value){ if(value){ doWithValue(value); }else{ db.get('key', function(err, value){ Memcache.set('key', value); doWithValue(value); }); } });
  • 8. 解决方案 ● 封装代码 ● “ 编译” ● https://github.com/Sage/streamlinejs ● 辅助函数 ● https://github.com/willconant/flow-js ● http://howtonode.org/step-of-conductor
  • 9. flow.exec( Flow-js 示例代码 function() { fs.rename("/tmp/hello", "/tmp/world", this); },function(err) { if (err) throw err; fs.stat("/tmp/world", this) },function(err, stats) { if (err) throw err; sys.puts("stats: " + JSON.stringify(stats)); } ); 其实吧,只是权宜之计~
  • 10. 更多 Flow control / Async goodies https://github.com/joyent/node/wiki/modules#async-flow
  • 11. Coroutine( 协程 )? Cooperative threading of any sort is a bad idea. --ry@jsconf2010 ● 讨论: ● http://shiningray.cn/node-js-coroutine.html ● http://news.ycombinator.com/item?id=1549168
  • 13. 博客首页: var data = {}; // 获取最新10篇博客文章 db.getPosts(10, function(err, posts){ data.posts = posts; }); // 获取最新10条评论 db.getComments(10, function(err, comments){ data.comments = comments; }); // 获取Tags列表 db.getTags(function(err, tags){ data.tags = tags; }); // view.render(data); 注: db 的方法都为异步操作
  • 15. function Combo(callback) { this.callback = callback; this.items = 0; } Combo.prototype = { add: function () { this.items++; }, finishOne: function () { this.items--; this.check(); }, check: function(){ if (this.items == 0) { this.callback.apply(this); } }; } 并行辅助函数 改自: http://howtonode.org/control-flow
  • 16. var data = {}; var combo = new Combo(function(){ view.render(data); }); 最终回调 // 获取最新10篇博客文章 combo.add(); db.getPosts(10, function(err, posts){ data.posts = posts; combo.finishOne(); }); // 获取最新10条评论 combo.add(); db.getComments(10, function(err, comments){ data.comments = comments; combo.finishOne(); }); // …. Combo 示例代码
  • 17. Google V8 与 单线程
  • 18. 线程模型 主线程 ● 主线程从左到右同时表示时间线 红色线代表的异步操作返回 ● 旁边的箭头代表异步操作 时,会发生什么情况呢? ● 主线程上的色块代表异步操作返回后, 执行代码所需的时间
  • 19. var t; function loop(){ t = Date.now(); for(var i=0; i< 10000*100000; i++){ //console.log(i); } }; function hello(){ console.log((Date.now() - t) + 'ms'); }; setTimeout(loop, 100); setTimeout(hello, 100);
  • 20. 主线程代码同步串行执行 ● 同一时间只有一个回调函数在执行 ● 异步回调会放到主线程的执行队列中, 如果主线程正在执行其他代码,则等待 调度,否则马上执行
  • 22. var http = require('http'); http.createServer(function (req, res) { for(var i=0; i < 100*100000; i++){ } res.writeHead(200); res.end('Hello World'); }).listen(8080, "127.0.0.1");
  • 23.
  • 24. Web Worker ● 耗 CPU 的操作放到 worker 中, 不阻塞主进程 ● 多 CPU 支持 ● 目前 Node.js 还不支持 Web Worker ● In future versions, Node will be able to fork new processes (using the Web Workers API ) which fits well into the current design. – nodejs.org ● https://github.com/pgriess/node-webworker
  • 26. var fs = require('fs'); try{ fs.readFile('noFile', function(err, data){ 如果异步回 if (err) throw err; 调中抛出异 console.log(data); 常会? } ); }catch(e){ console.log('error'); }
  • 28. process.on('uncaughtException', fn) 可以捕获到任何未捕获的异常 可是, 没有了上下文变量
  • 29. process.on('uncaughtException', function (err) { log(err); }); http.createServer(function(req, res){ try { mvcHandler(req, res); } 如果此函数内部 catch(e){ 有异步回调函数 res.writeHead(200); 中抛出异常,客 res.end('Server Error'); 户端则会得不到 } 响应 }).listen(8080, "127.0.0.1");
  • 31. 调试 ● http://cnodejs.org/blog/?p=911
  • 32. ECMAScript 5 ● Array ● indexOf(), lastIndexOf(), ● forEach(), map(), reduce(), filter(), every(), some() ● JSON ● JSON.parse(), JSON.stringify() ● Object.keys() ● Date.parse(), Date.now() ● __defineGetter__, __defineSetter__ ● 更多 :http://davidflanagan.com/Talks/es5/slides.html
  • 34. Forever ● 确保脚本在持续运行着 ● Github: https://github.com/indexzero/forever ● [sudo] npm install forever -g ● forever start run.js
  • 35. THX Q&A 联系我 ● ● http://qleelulu.cnblogs.com ● http:// 微博平台 /qleelulu ● qleelulu#gmail.com