Composer function 節點的基本介紹
前言
如果還不知道什麼是 Composer 的朋友們,可以先參考這篇 DigiRunnerAPI組合與設計 。
該篇範例會用到 debug 節點與 inject 節點,如果想深入了解這兩個節點的朋友,也可以參考以下這兩篇:
當遇到複雜邏輯處理且現有節點無法滿足需求時,我們會使用 function 節點來解決這些問題,
其節點內部提供使用者去撰寫 JavaScript,並在流經 function 節點時執行。
此篇將會分享設定介面如何使用以及提供一些範例給大家參考。
一、基本介紹
function 節點是屬於 Node-RED 的功能節點並且內部執行的語言皆為 JavaScript。
以下是節點設定介面的介紹:
(一) 函數介面:該介面是資訊流 (msg) 流經 function 節點時,會觸發此介面的程式碼。
(二) 設置介面:每次部署節點後都會執行設置介面內的程式碼。
(三) 關閉介面:每次重新部署節點或是節點停止後都會執行關閉介面內的程式碼。第一次部署該節點關閉介面內的程式碼不會執行。
(四) Setup 介面:
(1) 輸出如果是 2 ,就會如下圖所示有兩個輸出點。
這邊要注意的是輸出要為陣列,如果不是陣列,則默認從上面第一個輸出點輸出資訊,
而陣列第一個元素對應由上往下數第一個輸出點,第二個元素對應第二個輸出點,以此類推。
(2) 設定逾時。是執行階段允許 function 節點運作的時間,如超過時間則引發錯誤,並中斷流程。
此值以秒為單位,如果設定為 0(預設值),則不套用逾時。
(3) 可以在其中添加其他第三方模組並用於此 function 節點,其他所有的 function 節點也能引用此模組。
(五) 打開 library 介面:左邊介面為已儲存的 function 列表,並在選取時顯示節點資訊於右下方和右上方的函數介面。
讀取後會完全覆蓋並取代目前的 function 節點。
(六) 保存到 library 介面:保存該 function 節點內的所有資訊至 library,並在"匯出為"那邊自訂名稱。
二、節點效果與特性
在 function 節點中 coding 會如 IDE 一樣提示是否用現有的物件或方法,如下圖所示:
該節點除了有 JavaScript 內的原生方法外,還有 node-red 提供的一些物件做工具使用,
以下將會介紹 node-red 提供的物件:
(1) 一般項:
node.id :function 節點的 id
node.name :function 節點的名稱
node.outputCount:設定 function 節點的輸出數量
(2) log:紀錄
node.log(..)
node.warn(..)
node.error(..)
node.debug(..)
node.trace(..)
依造使用方法的等級,顯示 log 至右方的除錯面板和 dgR 的 online console 上,如下圖所示:
我在函數的地方使用 node.error("錯誤 LOG 測試"),當觸發並執行後會如以下顯示:
除錯面板:
online console:
(3) 節點狀態相關
node.on(..) :註冊事件處理程序
node.status(..) : 更新節點狀態
e.g. node.status({fill:"red",shape:"ring",text:"disconnected"});
node.send(..):非同步傳送訊息,使用此方法可以在 function 節點執行完畢 (output msg) 之前輸出訊息
node.done() : 以訊息結束,通常用於非同步情境
(4) context:節點範圍內的屬性
context.get(..):取得節點範圍的上下文屬性
context.set(..):設定節點範圍的上下文屬性
context.keys(..):傳回所有節點範圍的上下文屬性鍵的列表
context.flow: 與...一樣flow
context.global: 與...一樣global
(5) flow:API 流程範圍內的屬性
flow.get(..):取得流範圍的上下文屬性
flow.set(..):設定流範圍的上下文屬性
flow.keys(..):傳回所有流範圍上下文屬性鍵的列表
(6) global:全域屬性
global.get(..):取得全域範圍的上下文屬性
global.set(..):設定全域範圍的上下文屬性
global.keys(..):傳回所有全域範圍上下文屬性鍵的列表
(7) RED
RED.util.cloneMessage(..):安全地複製訊息對象,以便可以重複使用它,
相當於 deep copy 的作用。
(8) env
env.get(..): 取得環境變數
例如我在環境變量面板設置了 { "ssd": "159" },那當我呼叫 env.get("ssd") 則會得到 "159"。
三、簡單範例
這邊做了一個範例並用到一些剛剛介紹的 node-red 物件與方法來實現 HTTP 的請求,流程如下:
Setup 方面把輸出變為 2,設定如下:
其 function 節點內部程式碼如下圖所示:
我們在全域參數取得引用方法(註1),並引用了 JavaScript 內建的 http 模組,
const _require = global.get("require");
const http = _require('https');
接下來對 hello world api 進行請求,
回應後,我們使用了 node.send([msg, null]) 來發送得到的回應至 debug 34 節點,debug 35 節點不會收到任何東西
最後使用 node.done() 宣告此節點執行完畢。
而關於錯誤處理的部分,我們使用 http 模組的 on 來監聽 error 事件,當請求出錯時,
會發送錯誤訊息至 debug 35 節點,debug 34 節點不會收到任何東西。
註1:關於引用的方法 "require",雖然在 IDE 內會出現有此方法可以使用,如下圖所示:
但是實際上並無此方法,所以在 Composer 中可以使用 const _require = global.get("require") 來得到 "require" 模組。
四、結語
function 節點是個極度便利且能滿足大部分需求的節點,可以說只要懂 JavaScript 的工程師,都愛用它,
像是寧可使用 function 節點置換參數也不要用 converter 節點來置換,
但其實以小弟觀點來說,function 節點屬於解決需求的最後手段,因為 Composer 本質屬於可視化流程,可讀性、偵錯性與靈活性高,
如果將大量流程塞入 function 節點中,那這個黑盒子會降低可讀性、偵錯性與靈活性,所以建議小心服用。
五、參考文獻
(1) node-red 官方
(2) 自己