| 元字符 | 注解 |
|---|---|
| 行定位点:"^"和"$" | 这两个字符分别代表一行文字的开始和结束。例如,^mike将只会寻找以mike开始的行,同样mike$将只会寻找以mike结尾的行。 |
| 字符分类:"[]" | 一对方括号被称为字符分类,你可以用来匹配任何一个和多个字符。假设你想匹配单词"gray",同时也想找一下被拼写成"grey"的单词。使用一个字符分类将允许你匹配这两者——正则表达式gr[ea]y被解读成匹配这样的字符串,一个g,一个r,跟着或者是一个e或者是一个a,跟着时一个y。字符分类中的^表示否定。 |
| 字符分类中的元字符:"-" | 字符分类中的元字符"-"(dash)用来指出一个字符范围。字符分类[0123456789abcdefABCDEF]采用’-‘的话可以写成这样[0-9a-fA-F]。"-"只有在字符分类中才被认为是元字符。 |
| 选择性元字符:| | | (pipe)意思是"or"。它允许你把多个表达式合成一个表达式,然后匹配里面任何单个表达式的结果,这些子表达式被称为备选项。例如,Mike和Mickael是两个独立的表达式,但是Mike |
| 匹配可选项:"?" | "?"(question mark)意味着可选。它放在正则表达式的某个字符的后面,这个字符允许在匹配结果中出现,也可以不出现。 |
| 数量符号:"+"、"*" | 像"?"元字符一样,"+"(plus)和 "*"(star)元字符影响前导字符,可以匹配字符串中字符出现的数量("?"相当于0或者1次;"+"匹配一次或者多次;"*"表示匹配任何次)。 |
| 数量范围:"{}" | "{最小, 最大}"表示指定的特定项目可以被匹配的最少和最大次数。 |
| 转义字符:"\" | "\"(backslash)被用来转换指定元字符的含义,以便于把它们当成普通的字符来匹配。 |
| 圆括号:"()" | 大部分正则表达式工具允许你用圆括号设定一个特定的表达式子集。 |
| 句点:"." | "."(adot或point)是一种匹配任何字符的写法,在字符分类中"."就不是元字符了。 |
| 匹配边界:"\b" | 匹配一个单词边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\b就是匹配位置的)。例如,“er\b”可以匹配“remember”中的“er”,但不能匹配“pert”中的“er”。 |
| 匹配非边界:"\B" | 匹配非单词边界。“er\B”能匹配“pert”中的“er”,但不能匹配“remember”中的“er”。 |
| 匹配数字字符:"\d" | 匹配一个数字字符。等价于[0-9]。 |
| 匹配非数字字符:"\D" | 匹配一个非数字字符。等价于[^0-9]。 |
| 匹配换页符:"\f" | 匹配一个换页符。 |
| 匹配换行:"\n" | 匹配一个换行符。 |
| 匹配换页符:"\r" | 匹配一个换回车符。 |
| 匹配不可见字符:"\s" | 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 |
| 匹配任何可见字符:"\S" | 匹配任何可见字符。等价于[^ \f\n\r\t\v] |
| 匹配字母、数字、下划线:"\w" | 匹配字母、数字、下划线。等价于[A-Za-z0-9_] |
| 匹配非字母、数字、下划线:"\W" | 匹配非字母、数字、下划线。等价于[^A-Za-z0-9_] |
JavaScript 处理异步的几种方法
Javascript语言的执行环境是”单线程”(single thread)。为了解决由于执行耗时任务导致整个页面的卡顿的问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。
1 | // 可能会涉及到跨域请求的问题,tornado 解决方案: |
async/await
虽然 co 是社区里面的优秀异步解决方案,但是并不是语言标准,只是一个过渡方案。ES7语言层面提供 async/await 去解决语言层面的难题。
1 | const request = require('request'); |
tips:
- async 用来申明里面包裹的内容可以进行同步的方式执行,await则是进行执行顺序控制,每次执行一个 await,程序都会暂停等待 await 返回值,然后再执行之后的 await。
- await 后面调用的函数需要返回一个 promise,另外这个函数是一个普通的函数即可,而不是 generator。
- await 只能用在 async 函数之中,用在普通函数中会报错。
- await 命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try…catch 代码块中。
其实,async/await 的用法和 co 差不多,await 和 yield 都是表示暂停,外面包裹一层 async 或者 co 来表示里面的代码可以采用同步的方式进行处理。不过 async/await 里面的await 后面跟着的函数不需要额外处理,co 是需要将它写成一个 generator 的。
Promise
使用 Promise 可以很好的减少嵌套的层数,Promise 的实现采用了状态机,在函数里面可以很好的通过 resolve 和 reject 进行流程控制,可以按照顺序链式的去执行一系列代码逻辑。下面是使用 Promise 的一个例子:
1 | const request = require('request'); |
不过 Promise 仍然存在缺陷,它只是减少了嵌套,并不能完全消除嵌套。举个例子,对于多个 promise 串行执行的情况,第一个 promise 的逻辑执行完之后,我们需要在它的 then 函数里面去执行第二个 promise,这个时候会产生一层嵌套。
Generator
在 Node.js 中经常用的 tj/co 就是使用 generator 结合 promise 来实现的,co 是 coroutine 的简称,借鉴于 python、lua 等语言中的协程。它可以将异步的代码逻辑写成同步的方式,这使得代码的阅读和组织变得更加清晰,也便于调试。
1 | const co = require('co'); |
回调函数
这是异步编程最基本的方法。假定有两个函数fa和fb,后者等待前者的执行结果。如果fa是一个很耗时的任务,可以考虑改写fa,把fb写成fa的回调函数:
1 | // 改写前 |
回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合,流程会很混乱,而且每个任务只能指定一个回调函数。
1 | function a() { |
执行结果:
1 | oneSecond |
Redux & React-redux
Redux
Redux 是 JavaScript 状态容器,提供可预测化的状态管理。它由 Flux 演变而来,但受 Elm 的启发,避开了 Flux 的复杂性。
应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中。 惟一改变 state 的办法是触发 action,一个描述发生什么的对象。 为了描述 action 如何改变 state 树,你需要编写 reducers。reducer 只是一个接收 state 和 action,并返回新的 state 的函数。 对于大的应用来说,不大可能仅仅只写一个这样的函数,所以我们编写很多小函数来分别管理 state 的一部分:
1 | function visibilityFilter(state = 'SHOW_ALL', action) { |
再开发一个 reducer 调用这两个 reducer,进而来管理整个应用的 state:
1 | function todoApp(state = {}, action) { |
在vue中,可以使用vuex进行数据管理,在react中,可以使用redux进行数据管理。redux主要由Store、Reducer和Action组成:
- Store:状态载体,访问状态、提交状态、监听状态变更
- Reducer:状态更新具体执行者,纯函数(接收 state 和 action,并返回新的 state)
- Action:存放数据的对象,即消息的载体,只能被别人操作,自己不能进行任何操作
React-redux
Redux 的 React 绑定库是基于容器组件(Smart/Container Components)和展示组件(Dumb/Presentational Components)相分离的开发思想。
所有容器组件都可以访问 Redux store,所以可以手动监听它。一种方式是把它以 props 的形式传入到所有容器组件中。但这太麻烦了,因为必须要用 store 把展示组件包裹一层,仅仅是因为恰好在组件树中渲染了一个容器组件。
建议的方式是使用指定的 React Redux 组件
1 | connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]) |
连接 React 组件与 Redux store。
连接操作不会改变原来的组件类。
反而返回一个新的已与 Redux store 连接的组件类。
这种随处都可以使用、修改Redux中的数据的方式确实很方便,但Redux推荐的最佳实践还是在尽可能少的地方使用connect,把逻辑,数据相关的都放到容器组件中去处理,其他的组件都由容器组件所生成的props一层层传递下去然后渲染。