函数节点可以让我们使用JavaScript对传入的消息进行处理,然后返回多条消息,以使流程继续执行。
传入的消息一般以对象形式表示,其名称为msg
,通常都会包含一个msg.payload
属性,用来保存消息的主体内容。
其它类型的节点可能会在消息中附加其他专有属性,并且会在文档中加以详细说明。
输入函数节点的代码实际是JavaScript函数的主体部分,最简单的功能就是直接将收到的消息返回:
如果函数返回null
,那么就意味着没有消息传出,流程将被终止。
返回的消息对象不必于传入的对象保持一致,函数可以构建一个完全不同的新返回对象,比如:
msg.req
和msg.res
在端到端的传输过程中一致保留。通常情况下,函数节点应该返回它们所接收到的完整消息对象,只改变其中的某些特性。函数编辑器允许对输出端口数量进行修改。如果需要多个输出,那么可以通过返回一个消息数组,实现多端口传输功能。
这使得根据特定条件向不同端口发送消息成为可能。比如,以下函数中,将会把主题为banana
的消息发往第二个端口:
以下例子则会将原始消息发往第一个端口,而把包含载荷长度的消息发往第二个端口:
函数可以在结果数组中,以消息数组的方式输出多条消息。当多条消息被发往一个输出端口时,后续的节点将按照消息的排列顺序依次进行接收。
下例中的msg1
、msg2
、msg3
将发向第一个端口,msg4
则发往第二个输出端口。
以下的代码将接收到的载荷分解为词,然后按词逐条发送。
如果函数需要在发出消息前执行一个异步动作,那么就无法在其结束的部分立即返回消息。
解决的办法是,利用node.send()
函数,将传入的消息发送出去。比如:
如果在函数中使用了异步的回调代码,那么当流程重新部署时,可能需要对一些未处理的请求进行清理,或者,关闭所有的连接,这些都可以通过加入一个close
事件处理器来实现。
如果需要将节点的有关信息以日志方式输出到控制台,那么可以通过以下函数实现:
warn
和error
等信息也会被发往流程编辑器中的调试面板。
函数执行过程中,如果遇到有可能造成流程停止的错误时,将不会返回任何结果。为了能够触发同一个标签面板中的Catch节点,函数应该调用node.error
,并且将原始消息作为其第二个参数:
除msg
对象外,函数还可以将数据保存在context
对象中。
以下实例实现了函数执行次数的保存功能:
默认情况下,当Node-RED重启时,环境数据并不能被持久保存。
context
访问环境数据的:
var count = context.count;虽然这种方法目前仍被支持,但不赞成继续使用。为保证在今后的版本中,数据持久化相关功能仍然有效,建议使用
context.get
/context.set
函数。在Node-RED 0.13以上版本中,只有context
对象是作用于节点本地范围的,另有一个流程级别的环境对象可以实现同面板所有节点间数据分享,而不是只对Function节点,它是通过flow
对象来访问的:
There is also a global context available that is shared by, and accessible to all nodes. For example to make the variable foo available globally across the canvas: 还有一个全局环境对象,可以被所有节点访问。比如下面的变量foo能被全局访问到:
并且通过.get读取其保存的数值。
也可以在Node-RED启动时,用对象对全局环境进行预填充,这项功能是通过主settings.js文件中的functionGlobalContext项来设置的。
比如,为使所有函数都能访问预置的os
模块:
此时,该模块就能以global.get('osModule')
方式被引用了。
如果需要引用外部模块,必须首先利用npm将其手动安装到用户目录中。
cd ~/.node-red
npm i name_of_3rd_party_module_to_be_required
context
的子对象属性来访问全局环境的:
context.global.foo = "bar"; var osModule = context.global.osModule;虽然该方法仍然适用,但建议用
global.get
/global.set
替代它们,因为以这种方式所保存的数据会在未来版本中一直可用。
函数节点也可以像其他节点那样,为自身提供状态装饰功能。如果要设置状态,需调用node.status
函数。例如
详细参数说明参见节点状态文档
任何状态变化都能被Status节点(需Node-RED v0.12以上版本)所捕获。
Function节点还能使用以下模块及函数:
Buffer
- Node.js的Buffer
模块console
- Node.js的console
模块(node.log
是首选的日志方法)util
- Node.js的util
模块setTimeout/clearTimeout
- JavaScript的timeout函数setInterval/clearInterval
- JavaScript的interval函数注意: 无论何时,当流程停止或重新部署时,函数节点都会自动清除未完成的超时或间隔计时对象。