信号机制
Flask中的信号机制(Signal)与操作系统中的信号机制类似,都是通过信号来通知已经注册的回调函数,并使回调函数开始运行的机制。在Flask中的信号机制由blinker
库(官方推荐)提供支持,用于将函数注册到信号,并在触发信号时运行指定回调函数。信号机制主要用于将观察者模式中的各个模块之间解耦。
Flask定义了多个内置的信号,供应用监听特定事件,其中有一些是与请求钩子的触发位置相同,但是又有所不同。Flask内置的信号有以下这些:
template_rendered
: 模板成功渲染后触发。before_render_template
: 模板渲染之前触发。request_started
: 请求被处理之前触发。request_finished
: 请求的响应被发送给客户端之后触发。got_request_exception
: 请求处理过程中发生异常的第一时间触发。request_tearing_down
: 请求被销毁时触发,无论是否存在异常都会触发。appcontext_tearing_down
: 应用上下文被销毁时触发。appcontext_pushed
: 应用上下文被Push时触发。appcontext_popped
: 应用上下文被Pop时触发。message_flashed
: 发送Flash信息时触发。
信号与请求钩子不同,信号不能中止请求,并且其调用是无序的,并且信号是可以携带参数的,而请求钩子通常不携带参数。信号与RabbitMQ之类的消息队列功能类似,但是更加轻型。RabbitMQ之类的消息队列能够实现的功能更多,并且可以在不同系统之间传递消息,而信号只是限于Flask应用中进行简单的消息分发。
订阅一个信号,可以使用以下基于修饰器的简单方式。
from flask import template_rendered
@template_rendered.connect_via(app)
def when_template_rendered(sender, template, context, **kwargs):
pass
信号同样支持自定义,其需要用到blinker库中的signal
类。信号的建立和订阅方式可参考下例。
from blinker import signal
# 实例化信号
sign = signal('test')
# 订阅信号
@sign.connect
def each(arg):
pass
# 发送信号
sign.send(args)