Sequential message send from function node

Hi guys,

The Timer with UI feedback is being improved.

One of possible improvements (code-wise) is controlling the output via one node (bigtimer in this case), not making workarounds.

Accordingly to the guide, following line should just send messages and continue the function execution:

node.send([null, {payload: 'manual'}, null]);

An attempt to use following code sends just return message. I.e. async send doesn’t work.

node.send([null, {payload: 'manual'}, null]);
return([{payload: 10}, {payload: 1}, null]);

What’s wrong in node.send usage? Please, help to fix.
Thank you.

node.send([null, {payload: 'manual'}, null]); will work as you expect if it was called from within an async callback.

For example:

fs = require('fs')
fs.readFile('/etc/hosts', 'utf8', function (err,data) {
  if (err) {
    return;
  }
  node.send([null, {payload: data}, null]);
});

This means when readFile completes (it is async function) it will asynchronously send the payload to the next nodes.

This code:

node.send([null, {payload: 'manual'}, null]);
return([{payload: 10}, {payload: 1}, null]);

synchronously sends two messages to the output. These messages will eventually be processed asynchronously by the next (consuming) nodes (not very sure - should be clarified).

Btw I found interesting guide that touches parallel topics: Node-RED Design Patterns

Thank you, Petar.
Now I understand that I tried to use wrong functionality. Likely, I need to use syncrhonous or sequential send of messages: one after other in known order.

Is that possible in NR?

The same docs you linked to in your question show how to send multiple messages: https://nodered.org/docs/writing-functions.html#multiple-messages

You can either:

  1. call node.send multiple times:
    node.send(msg1); node.send(msg2); node.send(msg3);

  2. pass multiple messages to node.send in one go (an array of arrays…)
    node.send([ [ msg1, msg2, msg3 ] ])

  3. or, if this is at the end of your function, return an array of arrays
    return [ [ msg1, msg2, msg3 ] ]

3 Likes

@igrowing I've misread the question.

In fact node.send() will send your message to the output in async manner and your code will continue with the rest of the function.

May be the confusion comes because of the way node.send threats arrays. If you return an array then every element of that array will be sent to a particular output (and by default the function node has only 1 output). So if you return array of 3 objects your function node need to have 3 outputs. The number of outputs can be configured here:

image

The msg at index 0 will be sent to output 1, msg at index 1 goes to output 2 and msg at index 2 goes to output 3:

image

I've created a simple function to prove the theory:

image

As you can see on the first picture OUT2 have received two messages - one from node.send() and one from the return statement so node.send() is async in nature. OUT3 did not receive anything because you've sent null and nulls are silently discarded:

image

In your case you're sending null and {payload: 10} to output 1. Since nulls are discarded then only the second message will be delivered to the next node:

I think that's the reason you think node.send() is not async.

On the other hand if you want to return an array of objects to the first output you must send an array with one element. This one element should be an array of 3 objects (in your case) as @knolleary mentioned. All that depends on what you are trying to achieve.

Hope that helps more :slight_smile:

3 Likes