node学习笔记(三)

node之http

http协议是如何工作的:
1. http客户端发起请求,创建端口;
2. http服务器在端口监听客户端请求
3. http服务器向客户端返回状态和内容。

一个页面展示经历了什么?
  1. 域名解析;
  2. 查看有没有缓存DNS(浏览器自身的缓存和操作系统的自身的缓存)(chrome//net-internals/#dns);
  3. 读取本地host文件
  4. 浏览器发起DNS的一个系统调用
  5. 浏览器获得域名对应的IP地址后,发起HTTP经典的“三次”握手。

    1. A:你好,能听到我说话吗?
    2. B:听得到,听得到。
    3. A:开始聊天。
      拓展:断开连接时四次挥手:
      1. A:我不说了。
      2. B:等一下,我还没说完。
      3. B:好了,我说完了,我也不说了。
      4. A:好的,拜拜。
  6. TCP/IP连接建立起来后,浏览器就可以向服务器发送HTTP请求了,比如说用HTTP的GET方式请求一个根域里的一个域名,协议可以采用HTTP1.0的一个协议。

  7. 服务器端接收到了这个请求,根据路径参数,经过后端的一些 处理之后,把处理后的结果的数据(完整的HTML页面)返回给浏览器。

  8. 浏览器拿到完整的HTML页面代码之后,在解析和渲染这个页面的时候,里面的静态资源JS、CSS、图片、他们同样也是一个个HTTP请求,都需要经过上面的主要的七个步骤。

  9. 浏览器根据拿到的资源对页面进行渲染,最终把一个完整的页面呈现给用户。

写代码的过程中发现自己对很多概念的理解不是很准确,几个问题又出现在我的脑海:为什么这样写,node到底是什么,它的精髓在哪里?
总结过程中,发现以下几个概念的理解很重要
  1. 什么是回调?
    回调是异步编程最基本的方法,后续逻辑封装在回调函数中作为起始函数的参数 逐层去嵌套,通过这种方式让程序用我们所期望的方式走完流程。
  2. 什么是异步?
    程序的执行顺序和任务的排列顺序是不一致的,最基础的异步函数:setTimeout和setInterval
  3. 什么是阻塞I/O?
    input/output,程序执行过程中必然要进行很多I/O操作,读写文件、输入输出、请求响应等等。I/O操作时最费时的,至少相对于代码来说,在传统的编程模式中,举个例子,你要读一个文件,整个线程都暂停下来,等待文件读完后继续执行。换言之,I/O操作阻塞了代码的执行,极大地降低了程序的效率。
  4. 什么是非阻塞I/O?
    理解了阻塞I/O,那么非阻塞I/O就很好理解了。I/O操作不会阻塞程序的执行,也就是在I/O操作的同时,继续执行其他的代码(得益于node的事件循环机制)。
  5. 什么是事件驱动?
    当函数由于某个事件发生的时候而被调用执行的时候,这种函数调用的方式就叫做事件驱动。
  6. 什么是基于事件驱动的回调?
    我们注册的回调就是基于事件驱动的回调。
  7. 什么是事件循环(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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值