目录
升级 node 到当前稳定版
sudo npm install -g n
sudo n stable
查看装好的版本
node -v
v12.19.0
npm -v
6.14.8
typescript, gulp, cnpm
sudo npm un -g typescript
sudo npm i -g typescript
sudo npm un -g gulp
sudo npm cache clean -f
sudo npm i -g gulp@4.0.2
sudo npm un -g cnpm
sudo npm i -g cnpm
安装 node
推荐上面 升级的方式(方便快捷)。
下载自己合适的版本。
我下的是 node-v12.18.3-linux-x64, 解压后
把 node-v12.18.3-linux-x64/lib/node_modules 拷贝到 /usr/local/lib
然后在/usr/local/bin 创建 链接
sudo chmod +777 ../lib/node_modules/npm/bin/npm-cli.js
sudo ln ../lib/node_modules/npm/bin/npm-cli.js npm
lrwxrwxrwx 1 root root 38 2020-08-29 19:27 npm -> ../lib/node_modules/npm/bin/npm-cli.js
sudo ln -s /home/wjs/Downloads/node-v12.18.3-linux-x64/bin/node /usr/local/bin/
然后查看版本号, 有下面输出表示安装成功
~/Downloads/node-v12.18.3-linux-x64 $ node -v
v12.18.3
~/Downloads/node-v12.18.3-linux-x64 $ npm version
{
npm: '6.14.6',
ares: '1.16.0',
brotli: '1.0.7',
cldr: '37.0',
http_parser: '2.9.3',
icu: '67.1',
llhttp: '2.0.4',
modules: '72',
napi: '6',
nghttp2: '1.41.0',
node: '12.18.3',
openssl: '1.1.1g',
tz: '2019c',
unicode: '13.0',
uv: '1.38.0',
v8: '7.8.279.23-node.39',
zlib: '1.2.11'
}
我电脑上曾经提示下面错误
┌───────────────────────────────────────────────────────┐
│ npm update check failed │
│ Try running with sudo or get access │
│ to the local update config store via │
│ sudo chown -R $USER:$(id -gn $USER) /home/wjs/.config │
└───────────────────────────────────────────────────────┘
用下面的命令来解决
sudo chown -R wjs:$(id -gn wjs) /home/wjs/.config
源
npm set registry https://registry.npm.taobao.org/
查看源
npm config ls
debug
node --inspect acc.js
停在第一句
node --inspect-brk acc.js
安装chrome
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
卸载
sudo apt-get remove google-chrome-stable
打开 chrome
输入
chrome://inspect
点击 页面中的 inspect
断点,源码这些的都有
F10 下一步,不进函数
F11 进函数
grpc
node 安装的时候可能会很慢
npm i 后面指定下面的参数
npm i --grpc_node_binary_host_mirror=https://npm.taobao.org/mirrors/
--grpc_node_binary_host_mirror=https://npm.taobao.org/mirrors/
制作docker 镜像时添加 npm install --grpc_node_binary_host_mirror=https://npm.taobao.org/mirrors/
set
摘自 https://wangdoc.com/es6/set-map.html
类似于数组,但是成员的值唯一,无重复。
let s = new Set();
[2, 3, 2, 2].forEach(x => s.add(x));
console.log(s); // Set { 2, 3 }
遍历
var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for (var e of engines) {
console.log(e);
}
// Gecko
// Trident
// Webkit
* Set.prototype.add(value):添加某个值,返回 Set 结构本身。
* Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
* Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。
* Set.prototype.clear():清除所有成员,没有返回值。
* Set.prototype.keys():返回键名的遍历器
* Set.prototype.values():返回键值的遍历器
* Set.prototype.entries():返回键值对的遍历器
* Set.prototype.forEach():使用回调函数遍历每个成员
主要用途
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}
// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}
去除数组的重复值
[...new Set([1, 2, 3, 4, 4])] // 1 2 3 4
[...new Set('ababbc')].join('') // abc
注意
set中两个对象总是不相等的。
let set = new Set();
set.add({});
set.size // 1
set.add({});
set.size // 2
Map
摘自 https://wangdoc.com/es6/set-map.html
js的Object ,本质上也是个 map,但是key 只能是字符串。
Map 的key 可以是非字符串。Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
// 虽然 和 o 的值是一样的,但是指向了不同的地址
m.get({p: 'Hello World'}); // undefined
// 键/值对的数量
m.size // 1
m.has(o) // true
m.delete(o) // true
m.has(o) // false
遍历
let map = new Map().set('a', 1).set('b', 2);
for (let pair of map) {
console.log(pair);
}
// ['a', 1]
// ['b', 2]
for (let [key, value] of map) {
console.log(key + ' : ' + value);
}
// a : 1
// b : 2
转数组
const map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
[...map.keys()]
// [1, 2, 3]
[...map.values()]
// ['one', 'two', 'three']
[...map.entries()]
// [[1,'one'], [2, 'two'], [3, 'three']]
[...map]
// [[1,'one'], [2, 'two'], [3, 'three']]
数组转Map
将数组传入 Map 构造函数,就可以转为 Map。
new Map([
[true, 7],
[{foo: 3}, ['abc']]
])
// Map {
// true => 7,
// Object {foo: 3} => ['abc']
// }
mongodb
MongoDB 是一个基于分布式的文档数据库,nodejs的官方驱动是 mongodb
数据库推荐docker 安装 启动
// 下载
docker pull mongo
// 启动
sudo docker run -p 5555:27017 -v /home/wjs/wjsmongo:/data/db --name wjs_mongodb -d mongo
// 命令解释
-p 指定容器的端口映射,mongodb 默认端口为 27017
-v 为设置容器的挂载目录,这里是将<LocalDirectoryPath>即本机中的目录挂载到容器中的/data/db中,作为 mongodb 的存储目录
--name 为设置该容器的名称
-d 设置容器以守护进程方式运行
安装node驱动
npm i mongodb -s
简单使用
"use strict";
const { MongoClient } = require("mongodb");
// 数据库路径 数据库名 可以在 uri 中指定
const client = new MongoClient("mongodb://192.168.13.4:27017/wjs", {
useUnifiedTopology: true,
auth:{user:"wjs", password:"123456"}, // 账号密码只能在这里指定
});
async function run() {
try {
await client.connect();
const db = client.db();
const user = db.collection('user'); // 这里其实不会去发命令创建表格
// 表格不存在也没关系,会自动创建
// name 建唯一索引
await user.createIndex({name:1}, {unique:true});
// 增
let result = await user.insertOne({name:'孙悟空', address:'花果山'});
const _id = result.insertedId;
console.log(`插入的成功 ${_id}`);
// 查
const monkey = await user.findOne({_id});
console.log(monkey);
// 改 且返回 修改后的对象
const nmonkey = await user.findOneAndUpdate({_id}, { $set: {address:'养马场'} }, { returnOriginal: false });
console.log(nmonkey);
// 删
await user.removeOne({_id});
} finally {
// Ensures that the client will close when you finish/error
await client.close();
}
}
run().catch(console.log);
cmap
是mongodb驱动的连接池管理模块, 我猜是 Connection Management Access Protocol 的简称
3.6.2版本的cmap由下面6个文件组成
errors.js
定义了 PoolClosedError 和 WaitQueueTimeoutError 两个错误, 均以pool 为参数
stream_description.js
连接数据库时,会给数据库发送 admin.$cmd 的 ismaster 命令, 收到数据库应答时调用 StreamDescription的receiveResponse 方法
,得到数据库的类型 是Standalone 还是 RSPrimary 等。同时解析出数据库支持的 压缩,以及
'minWireVersion',
'maxWireVersion',
'maxBsonObjectSize',
'maxMessageSizeBytes',
'maxWriteBatchSize',
events.js
定义了连接池所有的事件
const CMAP_EVENT_NAMES = [
'connectionPoolCreated',
'connectionPoolClosed',
'connectionCreated',
'connectionReady',
'connectionClosed',
'connectionCheckOutStarted',
'connectionCheckOutFailed',
'connectionCheckedOut',
'connectionCheckedIn',
'connectionPoolCleared'
];
message_stream.js
MessageStream ,解析数据库发来的原始数据,装包发给数据库的数据
server.js connect() 的时候 会调用 this[kMonitor].connect();
monitor的connect() 开启了个定时调用,并且立马执行第一次 checkServer
checkServer 发现还没和数据库连接上,就执行 core/connection/connect.js 的 connect
connect(options, ... ) 的options是来自于 monitor, 而monitor在构造函数中就指定了 options.connectionType 是 cmap/connection的Connection
于是connect(options, ... )
connect会发起和数据库的连接,成功连上后在回调中根据 options.connectionType 生成了Connection 对象
参数 stream 实际上就是 驱动和数据库建立的 tcp socket
Connection(stream, options) 构造函数中
// hook the message stream up to the passed in stream
stream.pipe(this[kMessageStream]);
this[kMessageStream].pipe(stream);
这样驱动和数据库的连接的socket的数据就流给了 kMessageStream, 而kMessageStream的数据就流给了socket
数据库有数据发给驱动,socket 就收到数据,然后 write 给kMessageStream
驱动有命令发给数据库,就调用 kMessageStream 的writeCommand, 装好命令包后 push 给socket
denque
高性能的双向队列。 比double-ended-queue还快。
内部维护了个数组,head tail 下标。首部,尾部插入删除都非常快。 随机位置取值也只要计算下偏移位置,O1复杂度。
按2倍扩容,缩容。
用法示例
// npm i denque -s
const Denque = require('denque');
// 栈
let stack = new Denque();
let sz = stack.push(1); // push返回当前stack 尺寸
stack.push(2);
stack.size(); // 2
console.log(stack.pop()); // 2
console.log(stack.pop()); // 1
// 队列, 初值 1 2 3
let que = new Denque([1, 2, 3])
que.shift(); // 1 shift() 相当于 popFront() 删除并返回头部元素
que.shift(); // 2
que.shift(); // 3
que.push('item3'); // 尾部插入 item3
que.push('item4'); // item3 item4
que.unshift('item2'); // 头部插入 item2 item3 item4
que.unshift('item1'); // item1 item2 item3 item4
que.size(); // 4
que.get(2); // 随机取值, 性能极快 item2
que.get(3); // 随机取值, 性能极快 item3
que.peekFront(); // 获取头部元素 item1
que.peekBack(); // 获取结尾元素 item4
que.removeOne(2); // 删除中间元素 性能不佳
// que.remove(index, count); // 从index 开始的删除count个元素
que.clear(); // 清空
que.isEmpty(); // 是否为空
// splice(index, count) 删除 index开始的count个元素, 返回删除的元素,
// splice(index, count, ...args) 用 args 填充删除掉的空间
let q = new Denque([10,11,12,13,14,15,16,17,18,19]);
let ret = q.splice(1,5, 101, 102);
console.log(q.toArray()); // [10, 101, 102, 16,17,18,19]
console.log(ret); // [11,12,13,14,15]
underscore
npm i underscore
npm i @types/underscore -D
const _ = require('underscore');
// 复制一份
let cp = _.clone({name:'wjs', age:22})
// 删除指定元素 原数组不变
let a = ["wjs", "lj", "zlg", "wjs", "zy"];
let newOne = _.without(a, "wjs"); // [ 'lj', 'zlg', 'zy' ]
// 按指定属性排序
alldevs = _.sortBy(alldevs, 'devname')
let persons = [
{ detail: { age: 21} },
{ detail: { age: 23} },
{ detail: { age: 22} },
];
persons = _.sortBy(persons, p => p.detail.age)