5.4 context與global的應(yīng)用
5.4.1 使用context實(shí)現(xiàn)計(jì)數(shù)器
在之前的流中,我們總是在執(zhí)行函數(shù)節(jié)點(diǎn)時(shí)新建一個(gè)變量。函數(shù)節(jié)點(diǎn)執(zhí)行完畢以后,這個(gè)變量的值就會(huì)丟失,沒(méi)有辦法保存。如果需要保存一個(gè)變量的值該如何操作?
可以借助context對(duì)象。它可以理解為上下文,或者語(yǔ)境,用于保存內(nèi)存中的數(shù)據(jù),這個(gè)數(shù)據(jù)可以持續(xù)保存到下一個(gè)消息到來(lái)。Context可用于保存索引,計(jì)數(shù)或者消息中的數(shù)據(jù)。
拖入inject節(jié)點(diǎn)與debug節(jié)點(diǎn)。拖入一個(gè)函數(shù)節(jié)點(diǎn),進(jìn)行如下設(shè)置:
完成以后連線并部署。多次點(diǎn)擊inject節(jié)點(diǎn)的輸入按鈕,并在調(diào)試窗口觀察現(xiàn)象。
發(fā)現(xiàn)調(diào)試窗口中的數(shù)據(jù)在遞增
接下來(lái)結(jié)合現(xiàn)象分析代碼:
var
count = context.get(
'count')||
0;
count +=
1;
context.set(
'count',
count);
msg.payload =
count;
return msg;
我們可以查到Context的一些API(應(yīng)用程序接口)如下
context.get(..) : 獲取一個(gè)節(jié)點(diǎn)范圍內(nèi)的上下文屬性
context.set(..) : 設(shè)置一個(gè)節(jié)點(diǎn)范圍內(nèi)的上下文屬性
context.keys(..) : 返回所有節(jié)點(diǎn)范圍上下文屬性鍵的列表
context.flow : 同 flow
context.global : 同lobal
每次的輸入都不變,count每次都+1,最后輸出遞增的數(shù),說(shuō)明count記錄了上一次輸入的值。執(zhí)行Context.get以后,就可以獲取到之前保存的值。
執(zhí)行context.set以后,就能把處理過(guò)后的值保存下來(lái)。保存到哪里?’count’,帶單引號(hào)的count里。接下來(lái)用流程圖來(lái)表示邏輯。注意,帶單引號(hào)的’count’與變量count不一樣
流程保存在這里
[{"
id":
"1e2326a1.bc3da9","
type":
"inject","
z":
"dfef6fbd.55491","
name":
"","
topic":
"","
payload":
"1","
payloadType":
"num","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
690,"
y":
160,"
wires":
[["ecb5fce2.ce1dc"]]},{"
id":
"7e2fd11b.d4b4","
type":
"debug","
z":
"dfef6fbd.55491","
name":
"","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
1100,"
y":
160,"
wires":
[]},{"
id":
"ecb5fce2.ce1dc","
type":
"function","
z":
"dfef6fbd.55491","
name":
"計(jì)數(shù)器","
func":
"var count = context.get('count')||0;\n//如果count不存在就初始化為0,已存在則獲取count的值\ncount += 1;\ncontext.set('count',count);\n//執(zhí)行完+1操作以后保存count的值\nmsg.payload = count;\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
880,"
y":
160,"
wires":
[["7e2fd11b.d4b4"]]}]
5.4.2 使用flow在不同節(jié)點(diǎn)之間傳遞參數(shù)
在5.4.1小節(jié)中,函數(shù)節(jié)點(diǎn)計(jì)數(shù)器實(shí)現(xiàn)了用’count’來(lái)保存數(shù)據(jù)的方法,那么這個(gè)’count’里邊的內(nèi)容,能否被別的節(jié)點(diǎn)使用?我們來(lái)嘗試一下。
在上一章節(jié)的基礎(chǔ)上進(jìn)行修改,添加計(jì)數(shù)器2,并做如下修改:
如果計(jì)數(shù)器2可以使用’count’的內(nèi)容,那么payload里的內(nèi)容應(yīng)該是遞增的數(shù)據(jù)。然而,部署以后,觀察實(shí)驗(yàn)現(xiàn)象,可以發(fā)現(xiàn)OUT2的內(nèi)容并沒(méi)有變化。這說(shuō)明計(jì)數(shù)器2沒(méi)有辦法獲取’count’里的數(shù)據(jù)。
細(xì)心的讀者可以發(fā)現(xiàn),在context的API里,有這么一句解釋:
context.get(..) : 獲取一個(gè)節(jié)點(diǎn)范圍內(nèi)的上下文屬性
也就是使用context屬性只能影響一個(gè)節(jié)點(diǎn)范圍內(nèi)。然而在實(shí)際的應(yīng)用中,不同的節(jié)點(diǎn)之間可能會(huì)用到同一個(gè)變量,也就是說(shuō),有一個(gè)“全局變量”,該如何傳遞?
我們查閱了函數(shù)的API,找到了flow的context用法,地址是
https://nodered
.org/docs/writing-functions
flow
.get(..) : 獲得流作用域上下文屬性
flow
.set(..) : 設(shè)置流作用域上下文屬性
flow
.keys(..) : 返回所有流作用域上下文屬性鍵的列表
修改為“計(jì)數(shù)器”節(jié)點(diǎn)
修改“計(jì)數(shù)器2”節(jié)點(diǎn)
部署并點(diǎn)擊inject節(jié)點(diǎn)的輸入按鈕,看到現(xiàn)象如下
這說(shuō)明計(jì)數(shù)器2獲取到了計(jì)數(shù)器中的count值,也就是通過(guò)flow.set與flow.get實(shí)現(xiàn)了不同節(jié)點(diǎn)的參數(shù)傳遞。
流程分析如下:
流的信息保存在這里:
[{"
id":
"d5052172.91827","
type":
"inject","
z":
"a1f259d6.8791a8","
name":
"","
topic":
"","
payload":
"1","
payloadType":
"num","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
140,"
y":
180,"
wires":
[["9ddd2b2f.536d28"]]},{"
id":
"811f3cdb.bf65b","
type":
"debug","
z":
"a1f259d6.8791a8","
name":
"OUT1","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
530,"
y":
180,"
wires":
[]},{"
id":
"9ddd2b2f.536d28","
type":
"function","
z":
"a1f259d6.8791a8","
name":
"計(jì)數(shù)器","
func":
"var count = context.get('count')||0;\n//如果count不存在就初始化為0,已存在則獲取count的值\ncount += 1;\ncontext.set('count',count);\n//執(zhí)行完+1操作以后保存count的值\nflow.set('flowSave',count);\n//設(shè)置一個(gè)flowSave,來(lái)保存變量count的值\nmsg.payload = count;\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
330,"
y":
180,"
wires":
[["811f3cdb.bf65b","dbecc13a.c9642"]]},{"
id":
"dbecc13a.c9642","
type":
"function","
z":
"a1f259d6.8791a8","
name":
"計(jì)數(shù)器2","
func":
"var count = flow.get('flowSave')||0;\n//如果count不存在就初始化為0,已存在則獲取count的值\nmsg.payload = count;\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
450,"
y":
260,"
wires":
[["71a9791a.cd5f28"]]},{"
id":
"71a9791a.cd5f28","
type":
"debug","
z":
"a1f259d6.8791a8","
name":
"OUT2","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
610,"
y":
260,"
wires":
[]}]
5.4.3 使用flow實(shí)現(xiàn)計(jì)時(shí)器
使用flow的屬性在不同的節(jié)點(diǎn)之間傳遞參數(shù),這個(gè)功能十分有用。接下來(lái)嘗試使用flow實(shí)現(xiàn)一個(gè)節(jié)點(diǎn)執(zhí)行時(shí)間的計(jì)數(shù)器。
在JS中,可以使用Data對(duì)象的getTime方法獲取從1970年1月1日至今的毫秒數(shù)。跟時(shí)間戳得到的數(shù)據(jù)類似。在開(kāi)始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)分別獲取時(shí)間,兩個(gè)值的差就是這兩個(gè)節(jié)點(diǎn)之間所用的時(shí)間了。
另外,需要一個(gè)延時(shí)節(jié)點(diǎn)來(lái)放在兩個(gè)計(jì)時(shí)節(jié)點(diǎn)之間。在功能控件里恰好有一個(gè)名為“delay”的控件滿足要求。它可以控制消息通過(guò)自己的時(shí)間或者限制它的傳遞速度。我們會(huì)使用它的隨機(jī)延時(shí)的功能。
這次我們先來(lái)畫(huà)一個(gè)流程圖來(lái)分析思路。所謂“謀定而后動(dòng)”,在編程里也是一個(gè)好習(xí)慣。
這是開(kāi)始時(shí)間的設(shè)置
這是結(jié)束時(shí)間的設(shè)置
這是delay節(jié)點(diǎn)的設(shè)置
整個(gè)流連線如下。完成以后部署并點(diǎn)擊inject節(jié)點(diǎn)的輸入按鈕
可以看到,delay節(jié)點(diǎn)出現(xiàn)了一個(gè)藍(lán)色的標(biāo)記,以及表示時(shí)間的數(shù)字。這就是節(jié)點(diǎn)的狀態(tài)status。
調(diào)試窗口信息如下
這是代碼,懶得自己輸入的可以直接導(dǎo)入看結(jié)果。
[{"
id":
"710e935.672cf6c","
type":
"inject","
z":
"b0555ded.82baa","
name":
"","
topic":
"","
payload":
"","
payloadType":
"date","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
150,"
y":
200,"
wires":
[["c3b7267d.1578c8"]]},{"
id":
"8bc81259.86e39","
type":
"debug","
z":
"b0555ded.82baa","
name":
"","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
560,"
y":
200,"
wires":
[]},{"
id":
"c3b7267d.1578c8","
type":
"function","
z":
"b0555ded.82baa","
name":
"開(kāi)始時(shí)間","
func":
"flow.set('stratTime',new Date().getTime());\n//使用data對(duì)象的getTime方法獲取開(kāi)始時(shí)間,\n//并存到'startTime'里\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
260,"
y":
280,"
wires":
[["28cea295.2be12e"]]},{"
id":
"9152870f.6bf4e8","
type":
"function","
z":
"b0555ded.82baa","
name":
"結(jié)束時(shí)間","
func":
"var currentTime = new Date().getTime();\n//獲取當(dāng)前時(shí)間\nvar stratTime = flow.get('stratTime',stratTime);\n//用flow.get獲取之間節(jié)點(diǎn)儲(chǔ)存的開(kāi)始時(shí)間\nvar timeElapsed = (currentTime - stratTime)/1000;\n//計(jì)算時(shí)間差并從毫秒轉(zhuǎn)換為秒\nmsg.payload = \"逝去的時(shí)間是: \"+timeElapsed+\"s\";\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
460,"
y":
280,"
wires":
[["8bc81259.86e39"]]},{"
id":
"28cea295.2be12e","
type":
"delay","
z":
"b0555ded.82baa","
name":
"","
pauseType":
"random","
timeout":
"5","
timeoutUnits":
"seconds","
rate":
"1","
nbRateUnits":
"1","
rateUnits":
"second","
randomFirst":
"1","
randomLast":
"5","
randomUnits":
"seconds","
drop":
false,"
x":
350,"
y":
200,"
wires":
[["9152870f.6bf4e8"]]}]
5.4.4 使用全局變量
全局變量名為global,它與flow功能類似,但是作用域比f(wàn)low大,并且,即便重新部署,global儲(chǔ)存的值也不會(huì)丟失。以下是global的API。
global.
get(..) :獲取全局范圍的上下文屬性
global.
set(..) :設(shè)置全局范圍的上下文屬性
global.
keys(..) :返回所有全局作用域上下文屬性鍵的列表
在5.4.3中見(jiàn)到的例子使用global也完全可以實(shí)現(xiàn),只需要把里邊所有的“flow”換成“global”就可以,由于太簡(jiǎn)單,就不演示了。Flow的作用于只局限于同一個(gè)流,此處做一點(diǎn)flow做不到的事情——流之間的數(shù)據(jù)傳遞。程序設(shè)計(jì)思路如下:
整個(gè)流程如下設(shè)計(jì)
開(kāi)始時(shí)間與當(dāng)前時(shí)間分別設(shè)計(jì)如下
完成以后部署,并先點(diǎn)擊開(kāi)始時(shí)間的輸入按鈕,再點(diǎn)擊當(dāng)前時(shí)間的輸入按鈕。調(diào)試窗口現(xiàn)象如下:
從現(xiàn)象中可以看出來(lái)雖然兩個(gè)流沒(méi)有直接連接,但是第二個(gè)流仍然獲取了在第一個(gè)流中設(shè)置的變量。說(shuō)明實(shí)驗(yàn)成功。
接下來(lái),觀察重新部署時(shí),global變量能否保存。為節(jié)點(diǎn)做一些無(wú)關(guān)緊要的修改,例如out改為OUT,以便能夠點(diǎn)擊“部署”按鈕。
部署完成以后,不要點(diǎn)擊“開(kāi)始時(shí)間”的輸入按鈕,直接點(diǎn)擊“當(dāng)前時(shí)間”的輸入按鈕,可以觀察到如下的現(xiàn)象。
逝去的時(shí)間并沒(méi)有被重置,說(shuō)明重新部署不影響global的內(nèi)容。
程序的代碼保存在這里
[{"
id":
"eaf64e67.5277","
type":
"inject","
z":
"3769aa0d.6513d6","
name":
"開(kāi)始時(shí)間","
topic":
"","
payload":
"","
payloadType":
"date","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
140,"
y":
220,"
wires":
[["8a1f7741.6eb3b8"]]},{"
id":
"d6468738.ed2948","
type":
"debug","
z":
"3769aa0d.6513d6","
name":
"startTime","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
460,"
y":
220,"
wires":
[]},{"
id":
"8a1f7741.6eb3b8","
type":
"function","
z":
"3769aa0d.6513d6","
name":
"開(kāi)始時(shí)間","
func":
"global.set('stratTime',new Date().getTime());\n//使用data對(duì)象的getTime方法獲取開(kāi)始時(shí)間,\n//并存到'startTime'里\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
280,"
y":
220,"
wires":
[["d6468738.ed2948"]]},{"
id":
"4c55cdab.648834","
type":
"function","
z":
"3769aa0d.6513d6","
name":
"當(dāng)前時(shí)間","
func":
"var currentTime = new Date().getTime();\n//獲取當(dāng)前時(shí)間\nvar stratTime = global.get('stratTime',stratTime);\n//用global.get獲取之間節(jié)點(diǎn)儲(chǔ)存的開(kāi)始時(shí)間\nvar timeElapsed = (currentTime - stratTime)/1000;\n//計(jì)算時(shí)間差并從毫秒轉(zhuǎn)換為秒\nmsg.payload = \"逝去的時(shí)間是: \"+timeElapsed+\"s\";\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
280,"
y":
300,"
wires":
[["c5123924.d3f928"]]},{"
id":
"9f83e717.eaf888","
type":
"inject","
z":
"3769aa0d.6513d6","
name":
"當(dāng)前時(shí)間","
topic":
"","
payload":
"","
payloadType":
"date","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
120,"
y":
300,"
wires":
[["4c55cdab.648834","357d85e7.a522ba"]]},{"
id":
"c5123924.d3f928","
type":
"debug","
z":
"3769aa0d.6513d6","
name":
"OUT","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
440,"
y":
300,"
wires":
[]},{"
id":
"357d85e7.a522ba","
type":
"debug","
z":
"3769aa0d.6513d6","
name":
"crrentTime","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
280,"
y":
400,"
wires":
[]}]
接下來(lái),可以試一試不同的頁(yè)面內(nèi),global的數(shù)值能否傳遞。新建一個(gè)頁(yè)面。點(diǎn)擊這個(gè)加號(hào):
把第一個(gè)流放在“開(kāi)始的時(shí)間的流”標(biāo)簽下。第二個(gè)流放在“當(dāng)前時(shí)間的流”標(biāo)簽下。
部署,并先后點(diǎn)擊開(kāi)始時(shí)間與當(dāng)前時(shí)間的輸入按鈕,可以在調(diào)試窗口看到如下現(xiàn)象,說(shuō)明,即便是跨標(biāo)簽頁(yè),global的數(shù)據(jù)仍可以傳遞。
另外,我在官方的博客見(jiàn)到了沒(méi)有使用set與get方法的另外一種寫(xiě)法,經(jīng)過(guò)實(shí)驗(yàn)也可以使用,把它寫(xiě)在這里。
context.
global.startTime =
new Date().getTime();
//global.set(
'stratTime',
new Date().getTime());
var timeElapsed = (currentTime - context.
global.startTime)/
1000;
//var stratTime =
global.get(
'stratTime',stratTime);
//var timeElapsed = (currentTime - stratTime)/
1000;
5.5 函數(shù)控件的其它功能
函數(shù)控件的功能強(qiáng)大,甚至可以用函數(shù)控件實(shí)現(xiàn)其它所有功能控件的功能。在函數(shù)空間中,除了可以調(diào)用JS自帶的各種方法以外,含有一些node-red特有的API可以使用,我把它寫(xiě)在這里
node.id :函數(shù)節(jié)點(diǎn)的ID,在
0.19版本添加
node.name :函數(shù)節(jié)點(diǎn)的名字,在
0.19版本增加
node.log(..) : 記錄一條消息
node.warn(..) : 記錄一條警告消息
node.error(..) : 記錄一條錯(cuò)誤消息
node.debug(..) :記錄一條調(diào)試消息
node.trace(..) : 記錄跟蹤消息
node.on(..) : 注冊(cè)一個(gè)事件處理函數(shù)
node.status(..) : 更新節(jié)點(diǎn)的狀態(tài)
node.send(..) : 發(fā)送消息
這其中從log到trace都是用來(lái)向命令換輸出信息的,由于用法十分簡(jiǎn)單,就不講解了。
5.5.1 使用send方法發(fā)送數(shù)據(jù)
在5.2.3小節(jié)時(shí),我們遇到一個(gè)問(wèn)題:如果“apple”既滿足條件1,又滿足條件3,但是條件1執(zhí)行return 的操作以后,條件3就不再執(zhí)行了,有沒(méi)有既可以發(fā)送數(shù)據(jù),又不會(huì)結(jié)束函數(shù)的方法?當(dāng)然有。我們查詢了節(jié)點(diǎn)可以調(diào)用的API,發(fā)現(xiàn)有send函數(shù),滿足我們的要求。
查一下之前的代碼,把“判斷主題”節(jié)點(diǎn)做如下修改
然后部署并觀察現(xiàn)象,可以發(fā)現(xiàn),當(dāng)點(diǎn)擊apple的輸入按鈕時(shí),OUT1與OUT3都可以收到消息,說(shuō)明實(shí)驗(yàn)成功。
代碼如下
[{"
id":
"aaa307ba.874e58","
type":
"function","
z":
"b0555ded.82baa","
name":
"判斷主題","
func":
"if (msg.topic === \"apple\") {\n node.send([ msg, null, null]);\n} \nif(msg.topic === \"banana\"){\n node.send( [ null, msg, null]);\n}\nif(msg.topic.indexOf(\"e\") != -1){\n node.send([null,null, msg ]);\n}\n","
outputs":
3,"
noerr":
0,"
x":
360,"
y":
300,"
wires":
[["e8ac6685.9b2a48"],["503899c3.750508"],["1053e26d.f8c7ae"]]},{"
id":
"8e22df59.c7795","
type":
"inject","
z":
"b0555ded.82baa","
name":
"","
topic":
"apple","
payload":
"apple","
payloadType":
"str","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
150,"
y":
240,"
wires":
[["aaa307ba.874e58"]]},{"
id":
"1692dfa1.47a2a","
type":
"inject","
z":
"b0555ded.82baa","
name":
"","
topic":
"banana","
payload":
"banana","
payloadType":
"str","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
160,"
y":
300,"
wires":
[["aaa307ba.874e58"]]},{"
id":
"bb012d65.92486","
type":
"inject","
z":
"b0555ded.82baa","
name":
"","
topic":
"orange","
payload":
"orange","
payloadType":
"str","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
160,"
y":
360,"
wires":
[["aaa307ba.874e58"]]},{"
id":
"e8ac6685.9b2a48","
type":
"debug","
z":
"b0555ded.82baa","
name":
"OUT1","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
550,"
y":
240,"
wires":
[]},{"
id":
"503899c3.750508","
type":
"debug","
z":
"b0555ded.82baa","
name":
"OUT2","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
550,"
y":
300,"
wires":
[]},{"
id":
"1053e26d.f8c7ae","
type":
"debug","
z":
"b0555ded.82baa","
name":
"OUT3","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
550,"
y":
360,"
wires":
[]}]
5.5.2 流程之間傳遞函數(shù)
Context元素除了可以傳遞變量以外,也可以傳遞函數(shù)。我們?cè)诹?中新建一個(gè)名為hello的函數(shù),在流2中調(diào)用它。
流1的函數(shù)節(jié)點(diǎn)
流2的函數(shù)節(jié)點(diǎn)
先點(diǎn)擊IN1的輸入按鈕,再點(diǎn)擊IN2的輸入按鈕,可以看到OUT2中打印出了hello world,其中的“hello”是通過(guò)調(diào)用流1 的hello()函數(shù)打印出來(lái)的,說(shuō)明實(shí)驗(yàn)成功了。
代碼保存在這里
[{"
id":
"eaf64e67.5277","
type":
"inject","
z":
"3769aa0d.6513d6","
name":
"IN1","
topic":
"","
payload":
"","
payloadType":
"date","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
210,"
y":
160,"
wires":
[["1012b4b4.a746fb"]]},{"
id":
"d6468738.ed2948","
type":
"debug","
z":
"3769aa0d.6513d6","
name":
"OUT1","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
530,"
y":
160,"
wires":
[]},{"
id":
"1012b4b4.a746fb","
type":
"function","
z":
"3769aa0d.6513d6","
name":
"hello","
func":
"context.global.hello = function(){return \"hello\"};\nmsg.payload = context.global.hello();\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
370,"
y":
160,"
wires":
[["d6468738.ed2948"]]},{"
id":
"8331681d.a15558","
type":
"function","
z":
"3769aa0d.6513d6","
name":
"+world","
func":
"msg.payload = context.global.hello() + \" World\";\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
350,"
y":
260,"
wires":
[["8214b226.35f87"]]},{"
id":
"eff72cea.339ae","
type":
"inject","
z":
"3769aa0d.6513d6","
name":
"IN2","
topic":
"","
payload":
"","
payloadType":
"date","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
190,"
y":
260,"
wires":
[["8331681d.a15558"]]},{"
id":
"8214b226.35f87","
type":
"debug","
z":
"3769aa0d.6513d6","
name":
"OUT2","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"payload","
x":
520,"
y":
260,"
wires":
[]}]
5.5.3 使用狀態(tài)標(biāo)志
在5.4.3小節(jié)時(shí),我們第一次使用delay節(jié)點(diǎn),用于產(chǎn)生一個(gè)隨機(jī)數(shù)。此節(jié)點(diǎn)在在運(yùn)行的時(shí)候顯示出了一個(gè)表示時(shí)間的字符,顯示這個(gè)隨機(jī)的時(shí)間是多少。我覺(jué)得這個(gè)功能很有用,很直觀的可以顯示出我們感興趣的一些數(shù)據(jù)或狀態(tài),可以省去到處用debug節(jié)點(diǎn)打印的煩惱。翻看函數(shù)節(jié)點(diǎn)的API,正好有一條可以用來(lái)顯示狀態(tài):
node.status(..) : 更新節(jié)點(diǎn)的狀態(tài)
我們來(lái)研究一下如何使用。
首先要搭建一個(gè)可變的輸入信息,并且要持續(xù)一段時(shí)間,避免狀態(tài)變得太快看不到。相信詳細(xì)學(xué)過(guò)函數(shù)控件用法以后,對(duì)于聰明的你來(lái)說(shuō),這一定不是難事。——用函數(shù)節(jié)點(diǎn)+delay節(jié)點(diǎn)可以實(shí)現(xiàn)。先拖拽節(jié)點(diǎn),形成數(shù)據(jù)流。
第一個(gè)函數(shù)節(jié)點(diǎn)用于發(fā)送5個(gè)數(shù)字:
Delay節(jié)點(diǎn)用于限制數(shù)據(jù)包的速度,每秒一條。
如此就能實(shí)現(xiàn),第二個(gè)函數(shù)節(jié)點(diǎn)每秒接收到一個(gè)數(shù)字。
第二個(gè)函數(shù)節(jié)點(diǎn)的代碼如下:
node.status(
{fill:"green",shape:"dot",text:"Received "+msg.payload});
return msg;
也很好理解:填充綠色的點(diǎn),文本顯示“Received + 載荷”,只是格式死板一點(diǎn),照著填寫(xiě),不要遺漏標(biāo)點(diǎn)或拼寫(xiě)錯(cuò)誤。
接下來(lái)點(diǎn)擊inject的輸入按鈕,可以在調(diào)試窗口看到每隔一秒收到一個(gè)數(shù)據(jù)。這都是意料中的現(xiàn)象。
同時(shí),第二個(gè)函數(shù)節(jié)點(diǎn)也能顯示出一些信息。綠色的點(diǎn),以及顯示內(nèi)容都是我們代碼中自己編寫(xiě)的,所以,任務(wù)完成。
代碼在這里
[{"
id":
"5e91200b.6cd0c","
type":
"inject","
z":
"3769aa0d.6513d6","
name":
"","
topic":
"","
payload":
"","
payloadType":
"date","
repeat":
"","
crontab":
"","
once":
false,"
onceDelay":
0.1,"
x":
140,"
y":
120,"
wires":
[["27878fd7.889b1"]]},{"
id":
"27878fd7.889b1","
type":
"function","
z":
"3769aa0d.6513d6","
name":
"send1-5","
func":
"for (var i=0; i<5 ; i++){\n node.send({payload:i});\n}\nreturn null;","
outputs":
1,"
noerr":
0,"
x":
240,"
y":
200,"
wires":
[["b99e8ad0.ce0d28"]]},{"
id":
"4705bd05.3042f4","
type":
"debug","
z":
"3769aa0d.6513d6","
name":
"","
active":
true,"
tosidebar":
true,"
console":
false,"
tostatus":
false,"
complete":
"false","
x":
630,"
y":
120,"
wires":
[]},{"
id":
"b99e8ad0.ce0d28","
type":
"delay","
z":
"3769aa0d.6513d6","
name":
"","
pauseType":
"rate","
timeout":
"5","
timeoutUnits":
"seconds","
rate":
"1","
nbRateUnits":
"1","
rateUnits":
"second","
randomFirst":
"1","
randomLast":
"5","
randomUnits":
"seconds","
drop":
false,"
x":
370,"
y":
120,"
wires":
[["1d46ef67.107e81"]]},{"
id":
"1d46ef67.107e81","
type":
"function","
z":
"3769aa0d.6513d6","
name":
"received1-5","
func":
"node.status({fill:\"green\",shape:\"dot\",text:\"Received \"+msg.payload});\nreturn msg;","
outputs":
1,"
noerr":
0,"
x":
510,"
y":
200,"
wires":
[["4705bd05.3042f4"]]}]
總結(jié)
以上是生活随笔為你收集整理的node-red教程 5.4 context global与函数节点的其它功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。