摘要:使用了一个事件驱动非阻塞式的模型,使其轻量又高效。依赖就近,延迟执行。使用错误处理中间件默认情况下,给出的响应是状态码,包含文本以及错误自身详细信息的响应主体。
Node.js是什么
官网定义:
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式I/O 的模型,使其轻量又高效。
非阻塞 I/O 模型(non-blocking I/O model),简单点讲就是每个函数都是异步的,最后由 Libuv 这个 C/C++ 编写的事件循环处理库来处理这些 I/O 操作,隐藏了非阻塞 I/O 的具体细节,简化并发编程模型,让你可以轻松的编写高性能的Web应用,所以它是轻量(lightweight)且高效(efficient)的。
Node.js能做什么1)跨平台:覆盖你能想到的面向用户的所有平台,传统的PC Web端,以及PC客户端 nw.js/electron 、移动端 cordova、HTML5、react-native、weex,硬件 ruff.io 等
2)Web应用开发:网站、Api、RPC服务等
3)前端:三大框架 React Vue Angular 辅助开发,以及工程化演进过程(使用Gulp /Webpack 构建 Web 开发工具)
4)工具:npm上各种工具模块,包括各种前端预编译、构建工具 Grunt / Gulp、脚手架,命令行工具,各种奇技淫巧等
其实,一般使用是不需要掌握上图中的所有技术的。对于初学者来说,先够用,再去深究细节。所以,精简一下,只了解3个就足够足够用了。
Promise 的最大优势是标准化,各类异步工具库都按照统一规范实现,即使是async函数也可以无缝集成。所以用 Promise 封装 API 通用性强,用起来简单,学习成本低。在async函数普及之前,绝大部分应用都是采用Promise来做异步流程控制的,所以掌握Promise是Node.js学习过程中必须要掌握的重中之重。
推荐学习资料
Node.js最新技术栈之Promise篇 https://cnodejs.org/topic/560...
理解 Promise 的工作原理 https://cnodejs.org/topic/569...
Promise 迷你书 http://liubin.github.io/promi...
浏览器中非阻塞I/O的例子
Node中的非阻塞I/O示例
CommonJS
通过 require 来加载模块。
通过 exports 和 modul.exports 来暴露模块中的内容。
// moduleA.js module.exports = function( value ){ return value * 2; // moduleB.js var multiplyBy2 = require("./moduleA"); var result = multiplyBy2(4);
CommonJS是同步加载模块,服务器端的Node.js遵循CommonJS规范。
require("module"); require("../file.js"); exports.doStuff = function() {}; module.exports = someValue;
AMD
AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。AMD规范其实只有一个主要接口 define(id,dependencies,factory),它要在声明模块的时候指定所有的依赖dependencies,并且还要当做形参传到factory中,对于依赖的模块提前执行,依赖前置。
define("module", ["dep1", "dep2"], function(d1, d2) { return someExportedValue; }); require(["module", "../file"], function(module, file) { /* ... */ });
CMD
CMD规范和AMD相似,尽量保持简单,并且与CommonJS和NodeJS的Modules规范保持了很大的兼容性。依赖就近,延迟执行。
define(function(require, exports, module) { var $ = require("jquery"); var Spinning = require("./spinning"); exports.doSomething = ... module.exports = ... })Node查找模块的步骤 中间件
中间件组件是一个JavaScript函数,按惯例会接受三个参数:一个请求对象, 一个响应对象,还有一个通常命名为next的参数,它是一个回调函数,表明这个组件已经完成了它的工作,可以执行下一个中间件组件了。
Connect
最小的Connect程序
var connect = require("connect"); var app = connect(); app.listen(3000);
日志中间件
var connect = require("connect"); function logger(req, res, next) { console.log("%s %s", req.method, req.url); next(); } function hello(req, res) { res.setHeader("Content-Type", "text/plain"); res.end("hello world"); } connect() .use(logger) .use(hello) .listen(3000);
中间件的顺序很重要
用中间件的顺序执行认证
var connect = require("connect"); connect() .use(logger) .use(restrictFileAccess) .use(serveStaticFiles) .use(hello) .listen(3000);
挂载中间件和服务器
路由admin请求
function admin(req, res, next) { switch (req.url) { case "/": res.end("try /users"); break; case "/users": res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify(["tobi", "loki", "jane"])); break; } }
挂载中间件或服务器
var connect = require("connect"); connect() .use(logger) .use("/admin", restrict) .use("/admin", admin) .use(hello) .listen(3000);
创建可配置中间件
function setup(options) { // 设置逻辑 return function(req, res, next) { // 中间件逻辑 } } app.use(setup({some: "options"}));
创建可配置的logger中间件组件
var app = connect() .use(logger(":method :url")) .use(hello);
构建路由中间件组件
var connect = require("connect"); var router = require("./middleware/router"); var routes = { GET: { "/users": function(req, res) { res.end("tobi, loki, ferret"); }, "/user/:id": function(req, res, id) { res.end("user " + id); } }, DELETE: { "/user/:id": function(req, res, id) { res.end("deleted user " + id); } } }; connect() .use(router(routes)) .listen(3000);
因为程序里中间件的数量没有限制,中间件组件使用的次数也没有限制,所以在一个程序中 有可能会定义几个路由器。
var connect = require("connect"); var router = require("./middleware/router"); connect() .use(router(require("./routes/user"))) .use(router(require("./routes/admin"))) .listen(3000);
使用错误处理中间件
var connect = require("connect") connect() .use(function hello(req, res) { foo(); res.setHeader("Content-Type", "text/plain"); res.end("hello world"); }) .listen(3000);
默认情况下,Connect给出的响应是状态码500,包含文本“Internal Server Error”以及错误自 身详细信息的响应主体。
function errorHandler() { var env = process.env.NODE_ENV || "development"; return function(err, req, res, next) { res.statusCode = 500; switch (env) { case "development": res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify(err)); break; default: res.end("Server error); } } }
Connect自带的中间件
cookieParser(): 解析HTTP cookie
bodyParser(): 解析请求主体
limit(): 请求主体的限制
query(): 查询字符串解析
logger(): 记录请求
session(): 会话管理
static(): 静态文件服务
数据存储
内存, redis, mysql, mongodb, mongoose
渲染视图
处理表单和文件上传
阿里云,腾讯云,域名,pm2,nginx,集群,分布式,docker,微服务
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/98781.html
摘要:前端每周清单年度总结与盘点在过去的八个月中,我几乎只做了两件事,工作与整理前端每周清单。本文末尾我会附上清单线索来源与目前共期清单的地址,感谢每一位阅读鼓励过的朋友,希望你们能够继续支持未来的每周清单。 showImg(https://segmentfault.com/img/remote/1460000010890043); 前端每周清单年度总结与盘点 在过去的八个月中,我几乎只做了...
摘要:利用中间件实现异步请求,实现两个用户角色实时通信。目前还未深入了解的一些概念。往后会写更多的前后台联通的项目。删除分组会连同组内的所有图片一起删除。算是对自己上次用写后台的一个强化,项目文章在这里。后来一直没动,前些日子才把后续的完善。 欢迎访问我的个人网站:http://www.neroht.com/ 刚学vue和react时,利用业余时间写的关于这两个框架的训练,都相对简单,有的...
摘要:月号,杭州和联合主办的第八期技术分享会,在公司如期举行。张伟林,宋小菜资深前端开发工程师,年,霹雳迷,已手残的纸牌魔术师,喜欢神奇的东西,技术栈从上向下不断横向纵向贯穿,目前在寻找前后端大一统思想的路上越走越偏。 showImg(https://segmentfault.com/img/bVbkWN4?w=3000&h=1686); 12 月 9 号,杭州 NodeParty 和 Ro...
摘要:异步最佳实践避免回调地狱前端掘金本文涵盖了处理异步操作的一些工具和技术和异步函数。 Nodejs 连接各种数据库集合例子 - 后端 - 掘金Cassandra Module: cassandra-driver Installation ... 编写 Node.js Rest API 的 10 个最佳实践 - 前端 - 掘金全文共 6953 字,读完需 8 分钟,速读需 2 分钟。翻译自...
摘要:前言一直混迹社区突然发现自己收藏了不少好文但是管理起来有点混乱所以将前端主流技术做了一个书签整理不求最多最全但求最实用。 前言 一直混迹社区,突然发现自己收藏了不少好文但是管理起来有点混乱; 所以将前端主流技术做了一个书签整理,不求最多最全,但求最实用。 书签源码 书签导入浏览器效果截图showImg(https://segmentfault.com/img/bVbg41b?w=107...
阅读 3431·2019-08-30 13:15
阅读 1382·2019-08-29 18:34
阅读 799·2019-08-29 15:18
阅读 3464·2019-08-29 11:21
阅读 3205·2019-08-29 10:55
阅读 3642·2019-08-26 10:36
阅读 1854·2019-08-23 18:37
阅读 1804·2019-08-23 16:57