Node.js之Koa
Koa 是号称是 Node.js 的下一代 Web 开发框架,它是原 Express 团队设计的新的 Web 开发框架,不像 Express 使用回调函数的开发方式,在 Koa 中使用 asnyc 函数,使用同步的写法写出异步的代码,让开发有更好的开发体验。
入门按照惯例,我们使用 Koa 建立一个简单的 Web 服务器,向前端返回 Hello World!。首先下载 koa
npm install koa --save
接着在文件中导入 koa 使用即可
const Koa = require('koa');const app = new Koa();app.use(async ctx => { ctx.body = "Hello World!";});app.listen(3000);
上述代码我们引入了 Koa,接着使用 new Koa() 创建了一个服务,并且监听了 3000 端口。当有请求到来时,我们会直接返回 Hello World!。下面使用 Postman 发出一个 GET 请求,响应如下
...
罗马数字与数字的转换
罗马数字转数字题目描述罗马数包含以下七种字符
字符
数值
I
1
V
5
X
10
L
50
C
100
D
500
M
1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。通常情况下,罗马数字中小的数字在大的数字的右边。
但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字,输入确保在 1 到 3999 的范围内。
解题思路将罗马数字在每个位置的所有可能的取值列出,例如对于个位有如下情况
&quo ...
盛水最多的容器
题目描述给你 $n$ 个非负整数 $a_1, a_2, \dots, a_n$,每个数代表坐标中的一个点 $(i, a_i)$。在坐标内画出 $n$ 条垂直线,垂直线 $i$ 的两个端点 $(i, a_i)$ 和 $(i, 0)$。找出其中的两条线,使得它们与 $x$ 轴共同构成容器可以容纳最多的水。
说明:不能倾斜容器。
例如,给定如下非负整数 $[1, 8, 6, 2, 5, 4, 8, 3, 7]$
如图两条红色线形成的蓝色区域能够盛放最多的水,其值为 $7*7=49$。
解题思路最简单的思路就是遍历所有柱之间能够容纳多少流量,然后取最大值
public int maxArea(int[] height) { int max = 0; for (int i = 0; i < height.length - 1; i++) { for (int j = i + 1; j < height.length; j++) { max = Math.max(max, (j - i) * Math ...
Node.js之EventEmitter
EventEmitter 的使用EventEmitter 为我们提供了事件订阅机制,通过引入 events 模块来使用它。
const {EventEmitter} = require("events");const eventEmitter = new EventEmitter();// 监听 data 事件eventEmitter.on("data", () => { console.log("data");});// 触发 data 事件eventEmitter.emit("data");
上述代码我们使用 on 方法来为事件绑定回调函数,使用 emit 方法来触发一个事件。
on、addListener我们可以通过 on 和 addListener 方法来为某事件添加一个监听器,二者的使用是一样
eventEmitter.on("data", () => { console.log("data& ...
ES6:用模块封装代码
在早期,JavaScript 一般是用来当做独立执行的脚本,它们的程序比较小,随着 JavaScript 的发展,JavaScript 的程序也更加的复杂,所以就需要将程序按模块划分,并且模块之间可以互相导入,由此催生了很多的规范,如 CMD 与 AMD,现如今 ES6 也提供原生的模块机制支持。
模块真正的魔力所在是仅导出和导入你需要的绑定,而不是将所用东西都放到一个文件。只有很好地理解了导出和导入才能理解模块与脚本的区别。
模块的导出通过 export 关键字可以将一个值、函数、对象导出,如
export const a = 1;export function add(x, y) { return x + y;}export const obj = { name: "Alice", age: 18};export class Person { constructor(name) { this.name = name; }}
模块不支持动态 ...
ES6:Proxy和Reflect
在 ES6 之前我们很难模仿一个内置的对象的行为,例如模仿数组,当添加一个新的元素时,length 的长度 +1,当改变 length 的大小时,也会对数组中的元素产生影响,我们很难通过现有的语法去做到这件事情,在 ES6 中给我们提供了 Proxy,使得开发者能够创建内建的对象。
Proxy 可以为对象做一层代理,拦截对象的一些操作,例如为对象的属性赋值,访问对象的属性值,使用 in 操作判断对象是否存在某个属性等等,这些操作都可以被拦截,从而可以对要访问的属性进行验证从而决定采用什么行为。
let target = {};let proxy = new Proxy(target, {});proxy.name = "Alice";console.log(proxy.name); // Aliceconsole.log(target.name); // Aliceproxy.name = "Bob";console.log(proxy.name); // Bobconsole.log(target.n ...
ES6:Promise与异步编程
异步编程背景JavaScript 是单线程的,意味着同一时刻只有一处代码在执行,所以它的线程不能被阻塞住,为了达到这一个目的,JavaScript 使用任务队列的机制来实现异步编程。异步编程一般有两种模式
事件模型
回调模型
事件模型是指为某事件绑定一个函数,当事件触发时执行此函数,一般在 DOM 编程中比较常见,例如为按钮绑定点击事件
document.getElementById("btn").addEventListener("click", event => { // 处理点击事件})
回调模型在 Node.js 的 I/O 操作中比较常见,在读取文件时,我们肯定不能阻塞线程等待文件读取完毕,然后进行操作,这里的解决办法是在调用读取文件的函数时,传入一个函数,这个函数在文件被读取完成时会被调用,并且读取到的数据会作为参数传入该函数
const fs = require("fs");// 第二个参数是处理数据的回调函数,它会在文件读取完毕时执行fs.readFile("a.txt ...
ES6:改进的数组功能
Array 的新方法Array.of在 JavaScript 中,有两种方法创建一个数组,一个是通过构造函数 Array,另一个是通过字面量 [] 的方式。通过 Array 创建一个数组时,如果传入了一个数字 $n$,表示的是创建一个容量为 $n$ 的数组;如果传入了一个参数,但是不是一个数字,那么会创建一个包含该参数的数组;如果传入多个参数,那么创建一个包含这些参数的数组
let arr = new Array(2); // 创建长度为 2 的数组console.log(arr); // [ <2 empty items> ]arr = new Array("2");console.log(arr); // [ '2' ]arr = new Array(1, 2, 3);console.log(arr); // [ 1, 2, 3 ]
根据参数个数以及类型的不同,创建出的数组也不同,这种行为可能会为开发者带来记忆上的负担,所以在 ES6 中提供了一个 Array.of 方法,它可以接收多个参数,返回一个数组,数组中的元素就是传入的 ...
Node.js之Stream
引入 Stream假设我们有这么一个需求,我们需要复制一个文件中的内容到另一个文件中,我们会写出以下代码
const fs = require('fs');const path = require('path');const copy = (source, target) => { fs.readFile(path.resolve(source), (err, data) => { if(err) { throw new Error(err.toString()); return; } fs.writeFile(path.resolve(target), data, (err) => { if(!err) { console.log("复制成功!"); } ...
ES6:JavaScript中的类
JavaScript 不同于 Java、C++ 等典型的面向对象语言,JavaScript 在过去并没有类的概念,所以一些从 Java 或 C++ 等其他面向语言转过来的开发者会感到困惑,所以在 ES6 中引入了类的概念。
基本使用定义类使用关键字 class 声明一个类
class Person { constructor(name) { this.name = name; } sayHello() { console.log(`Hello ${this.name}`) }}let amy = new Person("Amy");amy.sayHello(); // Hello Amy
需要注意的是 class 只是一种语法糖,即一个 class 其实本质上就是一个函数
class Person { // ...}console.log(typeof Person); // function
类与构造函数 ...