diff --git a/packages/node_modules/@node-red/nodes/core/function/10-function.html b/packages/node_modules/@node-red/nodes/core/function/10-function.html index c0175788b..56c19fc25 100644 --- a/packages/node_modules/@node-red/nodes/core/function/10-function.html +++ b/packages/node_modules/@node-red/nodes/core/function/10-function.html @@ -9,7 +9,7 @@ -
+
@@ -29,8 +29,8 @@
-
-
+
+
@@ -45,8 +45,8 @@
-
-
+
+
@@ -129,19 +129,34 @@ value: $("#node-input-func").val(), globals: globals }); + var initCode = $("#node-input-initialize").val(); + var initText = RED._("node-red:function.text.initialize"); + var isEmptyInitCode = (initCode === ""); this.initEditor = RED.editor.createEditor({ id: 'node-input-init-editor', mode: 'ace/mode/nrjavascript', - value: $("#node-input-initialize").val(), + value: (isEmptyInitCode ? initText : initCode), globals: globals }); + if (isEmptyInitCode) { + var count = initText.split("\n").length; + this.initEditor.moveCursorTo(count -1, 0); + } + var finalCode = $("#node-input-finalize").val(); + var finalText = RED._("node-red:function.text.finalize"); + var isEmptyFinalCode = (finalCode === ""); this.finalizeEditor = RED.editor.createEditor({ id: 'node-input-finalize-editor', mode: 'ace/mode/nrjavascript', - value: $("#node-input-finalize").val(), + value: (isEmptyFinalCode ? finalText : finalCode), globals: globals }); + if (isEmptyFinalCode) { + var count = finalText.split("\n").length; + this.finalizeEditor.moveCursorTo(count -1, 0); + } + RED.library.create({ url:"functions", // where to get the data from @@ -266,11 +281,19 @@ node.editor.destroy(); delete node.editor; - $("#node-input-initialize").val(node.initEditor.getValue()); + var initCode = node.initEditor.getValue(); + if (initCode === RED._("node-red:function.text.initialize")) { + initCode = ""; + } + $("#node-input-initialize").val(initCode); node.initEditor.destroy(); delete node.initEditor; - $("#node-input-finalize").val(node.finalizeEditor.getValue()); + var finalCode = node.finalizeEditor.getValue(); + if (finalCode === RED._("node-red:function.text.finalize")) { + finalCode = ""; + } + $("#node-input-finalize").val(finalCode); node.finalizeEditor.destroy(); delete node.finalizeEditor; }, @@ -298,9 +321,9 @@ this.editor.resize(); var height = size.height; - $("#node-input-init-editor").css("height", (height -100)+"px"); - $("#node-input-func-editor").css("height", (height -120)+"px"); - $("#node-input-finalize-editor").css("height", (height -100)+"px"); + $("#node-input-init-editor").css("height", (height -105)+"px"); + $("#node-input-func-editor").css("height", (height -140)+"px"); + $("#node-input-finalize-editor").css("height", (height -105)+"px"); } }); diff --git a/packages/node_modules/@node-red/nodes/core/function/10-function.js b/packages/node_modules/@node-red/nodes/core/function/10-function.js index 4515f425c..14c8e9d49 100644 --- a/packages/node_modules/@node-red/nodes/core/function/10-function.js +++ b/packages/node_modules/@node-red/nodes/core/function/10-function.js @@ -92,8 +92,8 @@ module.exports = function(RED) { var node = this; node.name = n.name; node.func = n.func; - node.ini = n.initialize; - node.fin = n.finalize; + node.ini = n.initialize ? n.initialize : ""; + node.fin = n.finalize ? n.finalize : ""; var handleNodeDoneCall = true; @@ -122,14 +122,11 @@ module.exports = function(RED) { "};\n"+ node.func+"\n"+ "})(msg,send,done);"; - var iniText = "(async function () {\n"+node.ini +"\n})();"; - var finText = "(function () {\n"+node.fin +"\n})();"; var finScript = null; var finOpt = null; node.topic = n.topic; node.outstandingTimers = []; node.outstandingIntervals = []; - var initValue = undefined; var sandbox = { console:console, util:util, @@ -256,9 +253,6 @@ module.exports = function(RED) { if (index > -1) { node.outstandingIntervals.splice(index,1); } - }, - getInitValue: function() { - return initValue; } }; if (util.hasOwnProperty('promisify')) { @@ -273,13 +267,15 @@ module.exports = function(RED) { try { var iniScript = null; var iniOpt = null; - if (iniText || (iniText === "")) { + if (node.ini && (node.ini !== "")) { + var iniText = "(async function () {\n"+node.ini +"\n})();"; iniOpt = createVMOpt(node, " setup"); iniScript = new vm.Script(iniText, iniOpt); } node.script = vm.createScript(functionText, createVMOpt(node, "")); - if (finText || (finText === "")) { - finOpt = createVMOpt(node, "cleanup"); + if (node.fin && (node.fin !== "")) { + var finText = "(function () {\n"+node.fin +"\n})();"; + finOpt = createVMOpt(node, " cleanup"); finScript = new vm.Script(finText, finOpt); } var promise = Promise.resolve(); @@ -380,7 +376,6 @@ module.exports = function(RED) { }); promise.then(function (v) { - initValue = v; var msgs = messages; messages = []; while (msgs.length > 0) { diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html b/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html index c1c768f84..160cc5630 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html +++ b/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html @@ -21,7 +21,7 @@ the body of the message.

The function is expected to return a message object (or multiple message objects), but can choose to return nothing in order to halt a flow.

-

Setup code executed before deploy can be specified in Setup tab. Also, cleanup code executed before flow shutdown can be specified in Cleanup tab.

+

Setup code executed once whenever Node-RED is started or a new flow configuration is deployed can be specified in Setup tab. Also, cleanup code executed when the node is being stopped or re-deployed can be specified in Close tab.

Details

See the online documentation for more information on writing functions.

diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json index 7e7b73367..b48abb694 100755 --- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json @@ -208,9 +208,13 @@ "label": { "function": "Function", "initialize": "Setup", - "finalize": "Cleanup", + "finalize": "Close", "outputs": "Outputs" }, + "text": { + "initialize": "// Code added here will be run once whenever Node-RED is started\n// or a new flow configuration is deployed.\n", + "finalize": "// Code added here will be run when the node is being stopped\n// or re-deployed.\n" + }, "error": { "inputListener":"Cannot add listener to 'input' event within Function", "non-message-returned":"Function tried to send a message of type __type__" diff --git a/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html b/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html index ea6372180..b348512df 100644 --- a/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html +++ b/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html @@ -19,7 +19,7 @@

入力メッセージはmsgという名称のJavaScriptオブジェクトで受け渡されます。

msgオブジェクトはmsg.payloadプロパティにメッセージ本体を保持するのが慣例です。

通常、コードはメッセージオブジェクト(もしくは複数のメッセージオブジェクト)を返却します。後続フローの実行を停止したい場合は、オブジェクトを返却しなくてもかまいません。

-

デプロイ前に実行すべき初期化コードを初期化処理タブに、フローの停止時に実行すべき終了処理コードを終了処理タブに指定できます。

+

Node-REDの開始時もしくはフローの設定をデプロイした際実行される初期化コードを初期化処理タブに、ノードの停止もしくは再デプロイ時に実行される終了処理コードを終了処理タブに指定できます。

詳細

コードの書き方の詳細については、オンラインドキュメントを参照してください。

メッセージの送信

diff --git a/packages/node_modules/@node-red/nodes/locales/ja/messages.json b/packages/node_modules/@node-red/nodes/locales/ja/messages.json index d2bc5e4ee..1272fc8ae 100755 --- a/packages/node_modules/@node-red/nodes/locales/ja/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/ja/messages.json @@ -211,6 +211,10 @@ "finalize": "終了処理", "outputs": "出力数" }, + "text": { + "initialize": "// ここに記述したコードはNode-REDの実行開始時\n// もしくは新しいフローのデプロイ時に一度だけ実行されます。\n", + "finalize": "// ここに記述したコードはノードの停止時\n// もしくは再デプロイ時に実行されます。\n" + }, "error": { "inputListener": "コード内で'input'イベントのリスナを設定できません", "non-message-returned": "Functionノードが __type__ 型のメッセージ送信を試みました" diff --git a/test/nodes/core/function/10-function_spec.js b/test/nodes/core/function/10-function_spec.js index ec3effc88..ab7e4b486 100644 --- a/test/nodes/core/function/10-function_spec.js +++ b/test/nodes/core/function/10-function_spec.js @@ -1349,6 +1349,20 @@ describe('function node', function() { }); }); + it('should wait completion of initialization', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload = global.get('X'); return msg;",initialize:"global.set('X', '-'); return new Promise((resolve, reject) => setTimeout(() => { global.set('X','bar'); resolve(); }, 500));"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property("payload", "bar"); + done(); + }); + n1.receive({payload: "foo"}); + }); + }); + it('should execute finalization', function(done) { var flow = [{id:"n1",type:"function",wires:[],func:"return msg;",finalize:"global.set('X','bar');"}]; helper.load(functionNode, flow, function() {