2019-08 中旬 ✅
- 创建于:2019-08-11
- 更新于:2023-03-16

# 2019-08-20: koa 的 next 是什么 ✅✅
好好想想先 😌
参考链接
一句话
function compose(middleware) { return function (context, next) { // last called middleware # let index = -1 return dispatch(0) function dispatch(i) { if (i <= index) return Promise.reject(new Error('next() called multiple times')) index = i let fn = middleware[i] if (i === middleware.length) fn = next if (!fn) return Promise.resolve() try { return Promise.resolve(fn(context, dispatch.bind(null, i + 1))) } catch (err) { return Promise.reject(err) } } } }next在koa-compose中定义,可以延伸到 koa 中间件的洋葱模型。next 为递归调用。可以看见调用 next 后下一个中间件就会被执行。- 洋葱模型
- next 前置操作按中间件顺讯执行
- next 后置操作按中间件倒置执行
- 洋葱模型
# 2019-08-19: node worker_threads ✅✅
好好想想先 😌
参考链接
一句话
- 工作线程是为了处理 CPU 密集计算的,根据官方文档中的说法,node 内核提供的异步 IO 模型比工作线程来得高效得多,在 IO 中使用完全是浪费资源
# 2019-08-18: node vm(虚拟机) ✅✅
好好想想先 😌
参考链接
一句话
- vm 模块提供了在 V8 虚拟机上下文中编译和运行代码的一系列 API。vm 模块不是一个安全的虚拟机。不要用它来运行不受信任的代码。在这些文档中 "sanbox" 这个术语仅仅是为了表示一个单独的上下文,并不提供任何安全保障。
- JavaScript 代码可以被编译并立即运行,也可以编译、保存,以后再运行。
- 一个常见的场景是在沙盒中运行代码。沙盒中的代码使用不同的 V8 上下文,这意味着它具有与其余代码不同的全局对象。
- 可以通过上下文隔离化一个沙箱对象来提供上下文。沙盒代码将沙盒中的任何属性视为全局对象。由沙盒代码引起的任何全局变量的更改都将反映到沙盒对象中。
# 2019-08-17: v8(V8 引擎) ✅✅
好好想想先 😌
参考链接
一句话
util.callbackify- 将 promise 转换为回调函数util.promisify- 将回调函数转化为 promiseutil.deprecate- 方法废弃util.isDeepStrictEqual- 是否严格相等util.types.isXxx- 判断是否是某种类型
# 2019-08-16: Node process ✅✅
好好想想先 😌
参考链接
一句话
process.on()process.argvprocess.argv0process.cwd()process.envprocess.execArgvprocess.nextTick()process.exit()
# 2019-08-15: Node util (实用工具) ✅✅
好好想想先 😌
参考链接
一句话
util.callbackify- 将 promise 转换为回调函数util.promisify- 将回调函数转化为 promiseutil.deprecate- 方法废弃util.isDeepStrictEqual- 是否严格相等util.types.isXxx- 判断是否是某种类型
# 2019-08-15: Node stream (模块) ✅✅
好好想想先 😌
参考链接
一句话
- 流可以是可读的、可写的、或者可读可写的。 所有的流都是 EventEmitter 的实例。
- Node.js 创建的流都是运作在字符串和 Buffer(或 Uint8Array)上
- Node.js 中有四种基本的流类型:
- Writable - 可写入数据的流(例如 fs.createWriteStream())。
- Readable - 可读取数据的流(例如 fs.createReadStream())。
- Duplex - 可读又可写的流(例如 net.Socket)。
- Transform - 在读写过程中可以修改或转换数据的 Duplex 流(例如 zlib.createDeflate())。
- 此外,该模块还包括实用函数 stream.pipeline()、stream.finished() 和 stream.Readable.from()。
# 2019-08-14: Node module (模块) ✅✅
好好想想先 😌
参考链接
一句话
- 当 Node.js 直接运行一个文件时,require.main 会被设为它的 module。 这意味着可以通过 require.main === module 来判断一个文件是否被直接运行。
- 模块在第一次加载后会被缓存。模块是基于其解析的文件名进行缓存的。
- Node.js 有些模块会被编译成二进制。 这些模块别的地方有更详细的描述。核心模块定义在 Node.js 源代码的 lib/ 目录下。require() 总是会优先加载核心模块。
- 模块封装器
;(function (exports, require, module, __filename, __dirname) { // 模块的代码实际上在这里 })- exports 变量是在模块的文件级作用域内可用的,且在模块执行之前赋值给 module.exports。
- require.resolve - 使用内部的 require() 机制查询模块的位置,此操作只返回解析后的文件名,不会加载该模块。
# 2019-08-13: Node http 模块 ✅✅
好好想想先 😌
- 参考链接
- 一句话
- 常用方法
- http.createServer
- http.request
- http.get
# 2019-08-12: Node 架构 ✅✅
好好想想先 😌
- 参考链接
- 一句话
- Node Standard Library 是我们每天都在用的标准库,如 Http, Buffer 模块。
- Node Bindings 是沟通 JS 和 C++的桥梁,封装 V8 和 Libuv 的细节,向上层提供基础 API 服务。这一层是支撑 Node.js 运行的关键,由 C/C++ 实现。
- V8 是 Google 开发的 JavaScript 引擎,提供 JavaScript 运行环境,可以说它就是 Node.js 的发动机。
- Libuv 是专门为 Node.js 开发的一个封装库,提供跨平台的异步 I/O 能力。
- C-ares:提供了异步处理 DNS 相关的能力。
- http_parser、OpenSSL、zlib 等:提供包括 http 解析、SSL、数据压缩等其他的能力。
# 2019-08-11: JS 正则中的 ?:、?=、?!、?<=、?<! ✅✅
好好想想先 😌
参考链接
一句话
(?:x)- 匹配 'x' 但是不记住匹配项。这种括号叫作非捕获括号,使得你能够定义与正则表达式运算符一起使用的子表达式。看看这个例子 /(?:foo){1,2}/。如果表达式是 /foo{1,2}/,{1,2} 将只应用于 'foo' 的最后一个字符 'o'。如果使用非捕获括号,则 {1,2} 会应用于整个 'foo' 单词。更多信息,可以参阅下文的 Using parentheses 条目.
x(?=y)- 匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言。
- 例如,/Jack(?=Sprat)/会匹配到'Jack'仅仅当它后面跟着'Sprat'。/Jack(?=Sprat|Frost)/匹配‘Jack’仅仅当它后面跟着'Sprat'或者是‘Frost’。但是‘Sprat’和‘Frost’都不是匹配结果的一部分。
(?<=y)x- 匹配'x'仅仅当'x'前面是'y'.这种叫做后行断言。
- 例如,/(?<=Jack)Sprat/会匹配到' Sprat '仅仅当它前面是' Jack '。/(?<=Jack|Tom)Sprat/匹配‘ Sprat ’仅仅当它前面是'Jack'或者是‘Tom’。但是‘Jack’和‘Tom’都不是匹配结果的一部分。
x(?!y)- 仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找。
- 例如,仅仅当这个数字后面没有跟小数点的时候,/\d+(?!.)/ 匹配一个数字。正则表达式/\d+(?!.)/.exec("3.141")匹配‘141’而不是‘3.141’
(?<!y)x- 仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找。
- 例如, 仅仅当这个数字前面没有负号的时候,/(?<!-)\d+/ 匹配一个数字。
- /(?<!-)\d+/.exec('3') 匹配到 "3".
- /(?<!-)\d+/.exec('-3') 因为这个数字前有负号,所以没有匹配到。