[关闭]
@JunQiu 2018-09-18T09:31:18.000000Z 字数 6090 阅读 1724

回调函数和钩子函数(hook)、export(es6)、fastify

summary_2018/06 designIdea language_node fastify


1、日常工作


2、技术学习

  1. Incoming Request
  2. └─▶ Routing(路由匹配)
  3. └─▶ Instance Logger(实例化log)
  4. 404 ◀─┴─▶ onRequest Hook(执行onRequest Hook
  5. 4**/5** ◀─┴─▶ run Middlewares(执行中间件函数)
  6. 4**/5** ◀─┴─▶ Parsing(解析请求对象req->request
  7. 415 ◀─┴─▶ Validation(验证)
  8. 400 ◀─┴─▶ preHandler Hook
  9. 4**/5** ◀─┴─▶ beforeHandler(在handler执行前执行)
  10. 4**/5** ◀─┴─▶ User Handler(执行请求处理函数)
  11. └─▶ Reply(响应)
  12. └─▶ onSend Hook
  13. 4**/5** ◀─┴─▶ Outgoing Responseoutput响应)
  14. └─▶ onResponse Hook
  1. ###
  2. 1、如果在执行钩子过程中出现错误,只需将它传递给next()并且Fastify将自动关闭请求并将适当的错误代码发送给用户。(自定义错误代码传递给用户,使用reply.code())
  3. 2、可以在到达路由处理程序之前响应请求。比如认证钩子。如果您正在使用onRequest或中间件,请使用res.end。如果您正在使用preHandler挂钩,请使用reply.send
  4. 3、当fastify.close()被调用来停止服务器时触发。第一个参数是Fastify实例,第二个参数是done回调函数(结束回调)。
  5. 4beforeHandler不是标准钩子preHandler,在路由中注册,只会在指定的路由中执行。
  6. 5Application Hooks'onClose''onRoute'
  7. fastify.addHook('onRequest', (req, res, next) => {
  8. // some code
  9. next()
  10. })
  11. //注意钩子的参数,不同的阶段的参数代表的值不一样
  12. fastify.addHook('onRequest', async (req, res) => {
  13. // some code
  14. await asyncMethod()
  15. // error occurred
  16. if (err) {
  17. throw new Error('some errors occurred.')
  18. }
  19. return
  20. })
  21. fastify.addHook('preHandler', async (request, reply) => {
  22. // some code
  23. await asyncMethod()
  24. // error occurred
  25. if (err) {
  26. throw new Error('some errors occurred.')
  27. }
  28. return
  29. })
  30. fastify.addHook('onSend', async (request, reply, payload) => {
  31. // some code
  32. await asyncMethod()
  33. // error occurred
  34. if (err) {
  35. throw new Error('some errors occurred.')
  36. }
  37. return
  38. })
  39. fastify.addHook('onResponse', async (res) => {
  40. // some code
  41. await asyncMethod()
  42. // error occurred
  43. if (err) {
  44. throw new Error('some errors occurred.')
  45. }
  46. return
  47. })
  1. ## 应用级别
  2. module.exports = function (req, res, next) {
  3. next('test')
  4. }
  5. fastify.use(methodname)
  6. ##若需限制中间件到特殊路径
  7. //只需将路径作为第一个参数传递use
  8. // Single path
  9. fastify.use('/css', serveStatic(path.join(__dirname, '/assets')))
  10. // Wildcard path
  11. fastify.use('/css/*', serveStatic(path.join(__dirname, '/assets')))
  12. // Multiple paths
  13. fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets')))
  14. Tips not support routes with parameters, (eg: /user/:id/comments) and wildcard is not supported in multiple paths.
  15. ## 如果需要传入参数(参考express)
  16. const mid=require('./test1')
  17. fastify.use(mid(222))
  18. // mid
  19. module.exports = options=>function (req, res, next) {
  20. next(options)
  21. }
  22. Tips:中间件的请求和响应参数是原生 Nodejs Http req res,而路由中的 request reply 是经过 Fastify 封装的,两者并不一样
  23. ## 以插件的形式注入,register会创造新的上下文,可以使用fastify-plugin解决
  24. // pl
  25. const fp = require('fastify-plugin')
  26. module.exports = fp(function (fastify, opts, next) {
  27. const mid = function (req, res, next) {
  28. next(11111)
  29. }
  30. fastify.use(mid)
  31. next()
  32. })
  33. fastify.register(pl)
  1. ### decorateReply(you want to add new methods to the Reply core object. )
  2. fastify.decorateReply('utility', function () {
  3. // something very useful
  4. })
  5. //decorateRequest
  6. ### 依赖(添加一个字符串数组(表示您所依赖的装饰器的名称)作为第三个参数)
  7. fastify.decorate('utility', fn, ['greet', 'log'])
  1. ##使用
  2. fastify.register(plugin, [options])
  3. optionslogLevelprefix
  4. //创建一个插件非常简单,只需要创建一个带有三个参数的fastify实例,一个选项对象和下一个回调函数。
  5. Example:
  6. fastify.register(require('./routes/v1/users'), { prefix: '/v1' })
  7. // routes/v1/users.js
  8. module.exports = function (fastify, opts, next) {
  9. fastify.get('/user', handler_v1)
  10. next()
  11. }
  12. Tips:fastify, opts, next
  13. ## register产生新的上下文,然后传递给下一代
  14. fastify.register((instance, opts, next) => {
  15. instance.decorate('util', (a, b) => a + b)
  16. console.log(instance.util('that is ', ' awesome'))
  17. next()
  18. })
  19. fastify.register((instance, opts, next) => {
  20. console.log(instance.util('that is ', ' awesome')) // 抛出异常
  21. next()
  22. })
  1. ##作为属性
  2. module.exports = {
  3. };
  4. //exports被赋值,导出失败
  5. ##方式二
  6. module.exports.xx=xx;
  7. exports.xx=xx;
  1. ### export
  2. export var firstName = 'Michael';
  3. export var lastName = 'Jackson';
  4. #or
  5. var firstName = 'Michael';
  6. var lastName = 'Jackson';
  7. var year = 1958;
  8. export {firstName, lastName, year};
  9. ##别名
  10. function v1() { ... }
  11. function v2() { ... }
  12. export {
  13. v1 as streamV1,
  14. v2 as streamV2,
  15. v2 as streamLatestVersion
  16. };
  17. ##export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系
  18. // 报错
  19. export 1;
  20. // 报错
  21. var m = 1;
  22. export m;
  23. // 写法一
  24. export var m = 1;
  25. // 写法二
  26. var m = 1;
  27. export {m};
  28. // 写法三
  29. var n = 1;
  30. export {n as m};
  31. ###export default命令,为模块指定默认输出
  32. //export default命令只能使用一次
  33. //可以指定任意名字,import不要大括号
  34. //export default命令其实只是输出一个叫做default的变量
  35. // 正确
  36. export var a = 1;
  37. // 正确
  38. var a = 1;
  39. export default a;(赋值给default)
  40. // 错误
  41. export default var a = 1;
  42. ### import
  43. //import语句是 Singleton 模式(加载多个只会加载一个)
  44. import {firstName, lastName, year} from './profile.js';
  45. import * as circle from './circle';
  46. ##别名
  47. import { lastName as surname } from './profile.js';
  48. ##import命令输入的变量都是只读的,因为它的本质是输入接口。
  49. import {a} from './xxx.js'
  50. a = {}; // Syntax Error : 'a' is read-only;
  51. #禁止这种操作,本意用于提供只读,难排查错误
  52. import {a} from './xxx.js'
  53. a.foo = 'hello'; // 合法操作
  54. ##export、import复合写法
  55. export { foo, bar } from 'my_module';
  56. // 可以简单理解为
  57. import { foo, bar } from 'my_module';
  58. export { foo, bar };

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注