node学习笔记(三)
来源:互联网 发布:org.w3c.dom.node 编辑:程序博客网 时间:2024/06/08 07:13
node之http
http协议是如何工作的:
1. http客户端发起请求,创建端口;
2. http服务器在端口监听客户端请求
3. http服务器向客户端返回状态和内容。
一个页面展示经历了什么?
- 域名解析;
- 查看有没有缓存DNS(浏览器自身的缓存和操作系统的自身的缓存)(chrome//net-internals/#dns);
- 读取本地host文件
- 浏览器发起DNS的一个系统调用
浏览器获得域名对应的IP地址后,发起HTTP经典的“三次”握手。
- A:你好,能听到我说话吗?
- B:听得到,听得到。
- A:开始聊天。
拓展:断开连接时四次挥手:- A:我不说了。
- B:等一下,我还没说完。
- B:好了,我说完了,我也不说了。
- A:好的,拜拜。
TCP/IP连接建立起来后,浏览器就可以向服务器发送HTTP请求了,比如说用HTTP的GET方式请求一个根域里的一个域名,协议可以采用HTTP1.0的一个协议。
服务器端接收到了这个请求,根据路径参数,经过后端的一些 处理之后,把处理后的结果的数据(完整的HTML页面)返回给浏览器。
浏览器拿到完整的HTML页面代码之后,在解析和渲染这个页面的时候,里面的静态资源JS、CSS、图片、他们同样也是一个个HTTP请求,都需要经过上面的主要的七个步骤。
浏览器根据拿到的资源对页面进行渲染,最终把一个完整的页面呈现给用户。
写代码的过程中发现自己对很多概念的理解不是很准确,几个问题又出现在我的脑海:为什么这样写,node到底是什么,它的精髓在哪里?
总结过程中,发现以下几个概念的理解很重要
- 什么是回调?
回调是异步编程最基本的方法,后续逻辑封装在回调函数中作为起始函数的参数 逐层去嵌套,通过这种方式让程序用我们所期望的方式走完流程。 - 什么是异步?
程序的执行顺序和任务的排列顺序是不一致的,最基础的异步函数:setTimeout和setInterval - 什么是阻塞I/O?
input/output,程序执行过程中必然要进行很多I/O操作,读写文件、输入输出、请求响应等等。I/O操作时最费时的,至少相对于代码来说,在传统的编程模式中,举个例子,你要读一个文件,整个线程都暂停下来,等待文件读完后继续执行。换言之,I/O操作阻塞了代码的执行,极大地降低了程序的效率。 - 什么是非阻塞I/O?
理解了阻塞I/O,那么非阻塞I/O就很好理解了。I/O操作不会阻塞程序的执行,也就是在I/O操作的同时,继续执行其他的代码(得益于node的事件循环机制)。 - 什么是事件驱动?
当函数由于某个事件发生的时候而被调用执行的时候,这种函数调用的方式就叫做事件驱动。 - 什么是基于事件驱动的回调?
我们注册的回调就是基于事件驱动的回调。 - 什么是事件循环(Event Loop)?
如果有大量的异步操作,或者I/O耗时操作,以及定时器的延时操作,从而完成一些密集的任务,需要一个统一的机制来管理,这种机制就是事件循环。 (主线程从”任务队列”中读取事件,这个过程是循环不断的)。这个机制是什么样的呢:看了阮一峰老师的博客中关于Event Loop的一张图,醍醐灌顶:事件轮询的机制是,主线程 代码运行时会不断的产生堆和栈,而所有的异步回调函数会被压入栈中构成一个“回调队列”,当读取这个事件时,将调用与这个事件关联的JS函数代码,事件循环是先进先出的任务队列,整个任务队列是普通函数和回调函数构成的一个队列。
【以下内容摘自阮一峰老师博客】
但是,node中的运行机制如下,(与运行机制不同于浏览器)
(1)V8引擎解析JavaScript脚本。
(2)解析后的代码,调用Node API。
(3)libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。
(4)V8引擎再将结果返回给用户。
看了上面的概念之后,node的核心思想也不难理解:非阻塞,单线程,事件驱动。
异步之 回调函数方法 与 Promise对象方法 简单小实例
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <style> .ball{ width: 40px; height: 40px; border-radius: 20px; } .ball1{ background-color: red; } .ball2{ background-color: green; } .ball3{ background-color: yellow; } </style></head><body><div class="ball ball1" style="margin-left: 0"></div><div class="ball ball2" style="margin-left: 0"></div><div class="ball ball3" style="margin-left: 0"></div>
回调函数
<script> var ball1 = document.querySelector(".ball1"); var ball2 = document.querySelector(".ball2"); var ball3 = document.querySelector(".ball3"); function animate(ball,distance,callback) { setTimeout(function () { var marginLeft = parseInt(ball.style.marginLeft,10); if(marginLeft === distance){ callback(); }else { if(marginLeft < distance){ marginLeft++; }else { marginLeft--; } ball.style.marginLeft = marginLeft + 'px'; console.log(ball.style.marginLeft) animate(ball,distance,callback) } },13) } animate(ball1,100,function () { animate(ball2,200,function () { animate(ball3,300,function () { animate(ball3,150,function () { animate(ball2,150,function () { animate(ball1,150,function () { }) }) }) }) }) })</script>
Promise
<script> var ball1 = document.querySelector(".ball1"); var ball2 = document.querySelector(".ball2"); var ball3 = document.querySelector(".ball3"); function promiseAnimate(ball,distance) { return new Promise(function(resolve,reject) { function ani() { setTimeout(function () { var marginLeft = parseInt(ball.style.marginLeft,10); if(marginLeft === distance){ resolve() }else { if(marginLeft < distance){ marginLeft++; }else { marginLeft--; } ball.style.marginLeft = marginLeft + 'px'; console.log(ball.style.marginLeft); ani() } },10) } ani() }) } promiseAnimate(ball1,100) .then(function () { return promiseAnimate(ball2,200) }) .then(function () { return promiseAnimate(ball3,300) }) .then(function () { return promiseAnimate(ball3,150) }) .then(function () { return promiseAnimate(ball2,150) }) .then(function () { return promiseAnimate(ball1,150) })</script>
阅读全文
0 0
- node学习笔记(三)
- Node学习笔记(三)
- Node.js学习笔记之三:事件
- Node学习笔记(一)
- node学习笔记(一)
- node学习笔记(一)
- 《深入浅出Node.js》学习笔记——(三)异步I/O
- Node.js学习笔记之三:事件_EventEmitter
- node.js学习之路(三)
- 前端学习(三)node基础
- Node.js学习笔记(一)—— Node基础
- Node.js学习笔记(一)-认识Node.js
- Node.js学习笔记(1、简介)
- 学习笔记:Node.js(一)
- Node.js 学习笔记 (一)
- node.js学习笔记(一)
- Node.js学习笔记(1)
- node.js学习笔记(一)
- android 事件分发
- java IO流拷贝文件时出现文件夹“(拒绝访问)”的原因以解决方法
- CSS居中方法介绍
- NPM基本操作
- 程序启动
- node学习笔记(三)
- CString的几个使用方法
- iWatch开发的真机调试适配攻略
- php 计算两点地理坐标的距离
- 本地图片在线预览
- 关于druid数据连接池maven方式简易配置流程
- 结构体定义 typedef struct 用法详解和用法小结
- 不解压直接查看tar包内容
- 设计模式的艺术之道--桥接模式