今天的课主要讲了callback与正则表达式。
callback
callback
:主要是callback hell
的历史问题与callback hell
的解决方案
error-first
:node异步回调规范,将error参数
作为第一位。
// error-first 函数
(err, value) => {
}
util.callbackify
:接收一个async
函数(或者接收返回一个Promise
对象那个的函数),并返回一个遵循error-first回调风格
的函数。
const util = require('util');
// async function:
async function fn() {
return 'hello world!';
}
const callback = util.callbackify(fn);
callback((err, ret) => {
if(err) throw err;
console.log(ret);
})
// Promise function:
function fn() {
return Promise.reject(null);
}
const callback = util.callbackify(fn);
callback((err, ret) => {
err && err.hasOwnProperty('reason') && err.reason === null;
})
生成器generator function
,符合可迭代协议
和迭代器协议
。
// function* 生成器函数
function* gen() {
yield 1;
yield 2;
yield 3;
}
let g = gen();
// 返回一个yield表达式生成的值
Generator.prototype.next()
// 返回给定值,并结束生成器
Generator.prototype.return()
// 向生成器抛出一个错误
Generator.prototype.throw()
// 常用方法
g.next().value; // 当前yield的值
g.next().done; // 迭代器是否结束
es6新标准Promise
+ async/await
:
function resolveAfter2000ms() {
return new Promise((resolve, reject) => {
setTimetout(() => { resolve('1') }, 2000)
})
}
async function asyncCall() {
console.log('calling asyncCall: ');
// 执行asyncCall函数,会返回resolveAfter2000ms函数的值。
// 但是在asyncCall函数中执行的resolveAfter2000ms函数,则会返回resolve的值。
var result = await resolveAfter2000ms();
console.log(result);
}
promisify
: 接收一个error-first格式的函数,并返回一个Promise格式的对象。
const util = require('util');
const fs = require('fs');
// fs.stat满足最后一个参数是callback并且满足first-error的函数
const stat = util.promisify(fs.stat);
// promise风格
stat('.').then((stats) => {
// do something
}).catch((err) => {
// alert error
})
// async/await风格
async function callStat() {
var stats = await stat('.');
console.log(stats);
}
关于 管道 & Stream
:
其实这部分并没有完全吃透,看的内容也主要是解耦
,KISS
和拼装
。主要是为了程序的灵活和模拟日常生活中的零件化
。说白了就是跟插座一样,你一开始插的风筒,后面拔了插电热水壶,完全是不受影响,可以正常使用的。
正则表达式
关于 正则表达式
:
主要讲了历史以及匹配字符的用法。
元字符
.
:匹配 除换行符
以外的 任意字符
。
\w
:匹配 字母
或 数字
或 下划线
。
\W
:匹配不是 字母
、数字
、下划线
的字符。
\d
:匹配 数字
,相当于 [0-9]
。
\D
:匹配 非数字
的字符。
\s
:匹配任意 不可见字符
,包括 空格
、制表符
、换行符
等。
\S
:匹配任意 可见字符
。
^
:匹配字符串的 开始位置
。
$
:匹配字符串的 结束位置
。
量词
:
*
:重复 任意次
,相当于 {0,}
。
?
:重复 0次
或 1次
,相当于 {0,1}
。
+
:重复 1次
或 更多次
,相当于 {1,}
。
{n}
:重复 n次
。
{n,}
:重复 n次
或者 大于n次
。
{n,m}
:重复 n 到 m 次
。
分支 & 字符集
:
分支
:(a|b|c)
。
字符集
:符号为 [abc] === [a-c]
,[^abc] === [^a-c]
。
分组 & 引用
:
分组
:符号为 ()
。
分组例子
:/(\d{4})-(\d{2})-(\d{2})/
,一共3个括号,分了三组。
/(\d{4})-(\d{2})-(\d{2})/.match('2018-03-12');
// 会得到1个完整的匹配和3个分组。
// '2018-03-12' => 完整的匹配
// '2018' => 第一个分组
// '03' => 第二个分组
// '12' => 第三个分组
引用
:默认为 \+数字
,比如 \1 or \2 or \3
。
引用例子
:/(\d{4})-(\d{2})-\2/
,一共2个括号,1个引用,这里要注意,引用第2个,就必须匹配跟第2个引用
一模一样的值。
/(\d{4})-(\d{2})-\2/.match('2018-03-03');
=> true
/(\d{4})-(\d{2})-\2/.match('2018-03-04');
/(\d{4})-(\d{2})-\2/.match('2018-03-02');
/(\d{4})-(\d{2})-\2/.match('2018-03-11');
/(\d{4})-(\d{2})-\2/.match('2018-03-12');
=> false
零宽断言
,环视
,lookaround assertions
:
可在当前位置 向前
或者 向后
匹配,并且 不占字符串宽度
的正则匹配。
正向匹配→ | 逆向匹配 ← | |
---|---|---|
肯定 | (?=pattern) | (?<=pattern) |
否定 | (?!pattern) | (?<!pattern) |
/ab(?=c)d/.test('abcde');
=> false
// 注释:
// 如果lookaround assertions是占用宽度,那test函数返回的肯定是true。
// 但是这里返回的是false,说明ab(c)d中并不能匹配字符串的abcde,所以它是不占用宽度的。
惰性模式 & 贪婪模式:
贪婪模式 | 惰性模式 |
---|---|
尽可能多的去匹配 | 尽可能少的去匹配 |
默认 | 加个问号 |
.*, .+, .? | .*?,.+?,.?? |
修饰符 & 标志:
修饰符 | 全名 | 意义 |
---|---|---|
g | global | 全局搜索 |
i | ignoreCase | 不区分大小写 |
m | multiline | 多行搜索 |
y | sticky | “粘性”搜索 |
编不下去了…完。
网友评论