node.js--加深篇

服务器端

网站的组成

  • 网站的应用程序主要分为两大部分

    • 客户端: 在浏览器中运行的部分,就是用户看到并与之交互的界面程序,使用HTML、CSS、JavaScript构建
    • 服务器端:在服务器中运行的部分,负责存储数据和处理应用逻辑

在这里插入图片描述

网站服务器

网站服务器(Website Server)是指在互联网数据中心中存放网站的服务器

网站服务器主要用于网站在互联网中的发布、应用,是网络应用的基础硬件设施

它能够接收客户端的请求,能够对请求做出响应

IP地址

IP地址

IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址

IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异

IP协议中还有一个非常重要的内容,那就是给因特网上的每台计算机和其它设备都规定了一个唯一的地址,叫做**IP地址**

IP地址就像是我们的家庭住址一样,如果你要写信给一个人,你就要知道他(她)的地址,这样邮递员才能把信送到,计算机发送信息就好比是邮递员,它必须知道唯一的家庭地址才能不至于把信送错人家

IP地址是一个32位的二进制数,通常被分割为4个8位二进制数

域名

域名(英语:Domain Name),又称网域,是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时对计算机的定位标识(有时也指地理位置)

由于IP地址具有不方便记忆并且不能显示地址组织的名称和性质等缺点,人们设计出了域名,并通过网域名称系统(DNS,Domain Name System)来将域名和IP地址相互映射,使人更方便地访问互联网,而不用去记住能够被机器直接读取的IP地址数串
  • 域名入网结构
    • 主机名
    • 机构名
    • 网络名
    • 最高层域名

端口

端口是英文port的意译,可以认为是设备与外界通讯交流的出口。端口可分为虚拟端口和物理端口,其中虚拟端口指计算机内部或交换机路由器内的端口,不可见。例如计算机中的80端口、21端口、23端口等。物理端口又称为接口,是可见端口,计算机背板的RJ45网口,交换机路由器集线器等RJ45端口。电话使用RJ11插口也属于物理端口的范畴
  • 分类
    • 硬件端口
      • CPU通过接口寄存器或特定电路与外设进行数据传送,这些寄存器或特定电路称之为端口
      • 其中硬件领域的端口又称接口,如:并行端口、串行端口等
    • 网络端口
      • 在网络技术中,端口(Port)有好几种意思。集线器、交换机、路由器的端口指的是连接其他网络设备的接口,如RJ-45端口、Serial端口等。我们 这里所指的端口不是指物理意义上的端口,而是特指TCP/IP协议中的端口,是逻辑意义上的端口
    • 软件端口
      • 缓冲区

URL

URL是统一资源定位系统(uniform resource locator) 缩写

URL是因特网的万维网服务程序上用于指定信息位置的表示方法。它最初是由蒂姆·伯纳斯·李发明用来作为万维网的地址,现在它已经被万维网联盟编制为互联网标准RFC1738

创建WEB服务器

node是一门服务器语言,相比于之前的PHP语言,能做的事情更多

PHP可以做网站,node亦可        PHP不可以做的一些事,弄的则可以
//node方法启动一个web服务器

// 引入http模块
const http = require('http')
// 创建http服务
var app = http.createServer()
	/*	为app对象注册 request事件,当客户端有请求到达服务器后,会触发这个事件执行
	 *	回调函数中有两个参数
	 *	1)req:表示客户端的请求信息,可以从中获取客户端的信息
	 *	2)res:表示服务端的相应,可以使用此对象向客户端发送信息
	 */
app.on('request', (req, res) => {
	// 服务器必须向客户端发送响应信息后返回具体信息,否则客户端就会一直等待
	res.end('ok')
})
// 为服务区设置监听端口
app.listen(3000, () => {
	console.log('Server is running at http://127.0.0.1:3000')
})

HTTP

  • http状态码

    • 200 请求成功
    • 404 请求的资源没有被找到
    • 500 服务器端错误
    • 400 客户端请求有语法错误
  • 内容类型

    • text/html
    • text/css
    • application/javascript
    • image/jpeg
    • application/json

请求概述

超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)规定了如何从网站服务器传输超

文本到本地浏览器,它基于客户端服务器架构工作,是客户端(用户)和服务器端(网站)请求和应答的标准。
HTTP 协议就是计算机之间对话要遵循的格式(协议)

  • 具体来说分为三个步骤
    • DSN 解析,建立TCP连接,发送http请求
    • server接收到http请求,处理,并返回响应
    • 客户端接收到返回数据,并处理数据,如渲染页面,执行Js

在这里插入图片描述

Node.js异步编程

同步API, 异步API

  • 同步API:只有当前API执行完成后,才会继续执行下一个API
//同步执行
console.log('同步的');
console.log('API');
  • 异步API:当前API的执行不会阻塞后续代码的执行
console.log('同步的');  //先执行
setTimeout(
	() => { console.log('异步的');  //等待其他同步API执行完毕才执行
}, 1000);
console.log('同步的');  //先执行

同步API, 异步API的区别—值获取区别

同步API可以从返回值中拿到API执行的结果, 但是异步API拿不到
// 同步
function sum(n1, n2) {
    return n1 + n2;
}
var result = sum(5, 10);
console.log(result)   //输出5+10的结果   15
// 异步
function getMsg() {
    setTimeout(function() {
        return { result: '拿到了吗?' }
    }, 2000);
}
var result = getMsg();
console.log(result) //输出 undefined

回调函数

自己定义函数去给别人调用

// 定义函数f1
function f1(callback) {
    callback(1)
}
//调用f1函数
f1(function(sum) {
    console.log(sum); //输出回调的函数1
})

使用回调函数获取异步API执行结果

function f2(callback) {
    setTimeout(function() {
        callback(2)
    }, 100);
}
f2(function(num) {
    console.log(num);
});

同步API, 异步API的区别—代码执行的顺序

同步API从上到下依次执行,前面代码会阻塞后面代码的执行

for (var i = 0; i < 10; i++) {
    console.log('我是for循环代码第' + i + '次执行');
}
console.log('for循环执行完毕执行的代码');

异步API不会等待API执行完成后再向下执行代码

console.log('开始代码');
setTimeout(() => { console.log('1秒后执行的代码') }, 1000);
setTimeout(() => { console.log('0秒后执行的代码') }, 0);
console.log('结束代码');

代码执行顺序分析

  • 按照顺序从上到下执行代码
  • 遇到同步代码,直接执行
  • 遇到异步代码,放到异步代码执行区
  • 所有的同步代码执行完毕后,再开始按照顺序执行异步代码知行区中的代码
  • 执行完毕后,将回调函数放到回调函数队列(也在同步代码执行区域),然后执行
  • 因为异步任务的耗时不一样,所以可能排在前面的异步代码,反而最后才执行完,所以其回调函数可能最后才执行

Node.js中的异步API

  • 使用回调函数依次读取p1-p3 三个文件
  • 但输出结果是不定的,顺序也不同,原因是这三个异步的任务会同时执行,后面的不会等前面的
const fs = require('fs') //引入fs模块
//resolve 和 reject 是两个形参,表示两个回调函数
//成功了,调用resolve函数,失败了调用reject函数
var p1 = new Promise((resolve, reject) => {
	// 将异步代码写入此函数中
    fs.readFile('./p1.txt', 'utf-8', (err, data) => {
        if (err) {
            reject('读取失败,请检查下路径或者传值是否正确')
        } else {
            resolve(data)
        }
    })
})
/*异步任务结束后,
 *	如果成功了,会触发then事件,我们就传递一个实参进去,这个参数是一个函数,会赋值给上面的形参
 *	resolve
 *	如果失败了,会触发catch事件,我们就传递一个实参进去,这个参数是一个函数,会赋值给上面的形参
 *  reject
*/
p1.then(result => {
    console.log(result)
}).catch(err => {
    console.log(err)
})
var p2 = new Promise((resolve, reject) => {
    fs.readFile('./p2.txt', 'utf-8', (err, data) => {
        if (err) {
            reject('读取失败,请检查下路径或者传值是否正确')
        } else {
            resolve(data)
        }
    })
})
p2.then(result => {
    console.log(result)
}).catch(err => {
    console.log(err)
})
var p3 = new Promise((resolve, reject) => {
    fs.readFile('./p3.txt', 'utf-8', (err, data) => {
        if (err) {
            reject('读取失败,请检查下路径或者传值是否正确')
        } else {
            resolve(data)
        }
    })
})
p3.then(result => {
    console.log(result)
}).catch(err => {
    console.log(err)
})
  • 我们该如何控制函数的执行顺序?

    方法:我们应在一个函数的回调函数中,去执行另一个promise(代码写法如下)

const fs = require('fs') //引入fs模块
function txt() {
    return new Promise((resolve, reject) => {
        resolve('开始读取文件:')
    })
}

function p1() {
    return new Promise((resolve, reject) => {
        fs.readFile('./p1.txt', 'utf-8', (err, data) => {
            if (err) {
                reject('读取失败,请检查下路径或者传值是否正确')
            } else {
                resolve(data)
            }
        })
    })
}

function p2() {
    return new Promise((resolve, reject) => {
        fs.readFile('./p2.txt', 'utf-8', (err, data) => {
            if (err) {
                reject('读取失败,请检查下路径或者传值是否正确')
            } else {
                resolve(data)
            }
        })
    })
}

function p3() {
    return new Promise((resolve, reject) => {
        fs.readFile('./p3.txt', 'utf-8', (err, data) => {
            if (err) {
                reject('读取失败,请检查下路径或者传值是否正确')
            } else {
                resolve(data)
            }
        })
    })
}

function p4() {
    return new Promise((resolve, reject) => {
        fs.readFile('./p4.txt', 'utf-8', (err, data) => {
            if (err) {
                reject('读取失败,请检查下路径或者传值是否正确')
            } else {
                resolve(data)
            }
        })
    })
}

function p5() {
    return new Promise((resolve, reject) => {
        fs.readFile('./p5.txt', 'utf-8', (err, data) => {
            if (err) {
                reject('读取失败,请检查下路径或者传值是否正确')
            } else {
                resolve(data)
            }
        })
    })
}

function txt_w() {
    return new Promise((resolve, reject) => {
        resolve('文件读取完毕!')
    })
}
txt().then(result => {
    console.log(result);
    return p1();
}).then(result => {
    console.log(result);
    return p2();
}).then(result => {
    console.log(result);
    return p3();
}).then(result => {
    console.log(result);
    return p4();
}).then(result => {
    console.log(result);
    return p5();
}).then(result => {
    console.log(result);
    return txt_w();
}).then(result => {
    console.log(result);
    return;
})

异步函数

  • 普通函数定义前加async关键字 普通函数变成异步函数

  • 异步函数默认返回promise对象

  • 在异步函数内部使用return关键字进行结果返回 结果会被包裹的promise对象中 return关键字代替了resolve方法

  • 在异步函数内部使用throw关键字抛出程序异常

  • 调用异步函数再链式调用then方法获取异步函数执行结果

  • 调用异步函数再链式调用catch方法获取异步函数执行的错误信息

  • await 关键字

    • await关键字只能出现在异步函数中
    • await promise await后面只能写promise对象 写其他类型的API是不不可以的
      txt_w();
      }).then(result => {
      console.log(result);
      return;
      })

## 异步函数

- 普通函数定义前加async关键字 普通函数变成异步函数
- 异步函数默认返回promise对象
- 在异步函数内部使用return关键字进行结果返回 结果会被包裹的promise对象中 return关键字代替了resolve方法
- 在异步函数内部使用throw关键字抛出程序异常
- 调用异步函数再链式调用then方法获取异步函数执行结果
- 调用异步函数再链式调用catch方法获取异步函数执行的错误信息

- await 关键字
  - await关键字只能出现在异步函数中
  - await promise await后面只能写promise对象 写其他类型的API是不不可以的
  - await关键字可是暂停异步函数向下执行 直到promise返回结果

猜你喜欢

转载自blog.csdn.net/blue_698/article/details/113572844
今日推荐