I'm a little confused about
node.done() function and how to use it after a for loop.
Let's suppose that I have 10 messages to send async. I must tell nodered the that it has finished due to timeout issues.
In my example, I should only call
node.done() only after I every message went out, or after every
Great question - one that myself, is interested to know.
on the basis of :
If a Function node does asynchronous work with a message, the runtime will not automatically know when it has finished handling the message.
To help it do so, the Function node should call
node.done() at the appropriate time. This will allow the runtime to properly track messages through the system
I would say, your node is doing work with a message - it may send further messages multiple times using async methods - but doing so, its still "doing work".
so i would say after the last
send - but I don't know the correct answer - someone here will know however
You should call done when you have finished everything that is required by the message that went in. The purpose of it is so that a user of that node can tell when it has completed acting on the message that was sent in.
done() signifies that is it complete and ensures the
complete node operates.
If an error (like a timeout or something occurs) you should call done with the error e.g.
done(err) and then the
catch node will permit users to "catch" your error.
~Ignore me - I assumed wrong~
NOTE: Because you are talking about the
done function I assume you are talking about a custom node you are developing right?
Because it is not
node.done but is infact just
done (i.e. the callback passed into the 'on' 'input' handler) e.g...
what is the difference with node.error(...)? Saw yesterday something in the documentation, but it was not really clear to me.
Can I summarize it like this?
done() when the input message processing has finished succesfully.
done(err) when the input message processing has finished unsuccesfully.
node.error(err) when there is an error during the processing but you don't return after the error, so you keep on processing the input message.
node.error requires a 2nd parameter (the
msg) in order for the runtime and editor to know where the error originated.
node.done does not (it already knows because
done is passed into the VM).
Operationally, your summary is as good as any guide but to add my recollection of this...
node.done() is the "new" way of signalling an error and also a means of triggering the complete action but should really be used to indicate the overall operation is done (either cleanly or with an error).
As it happens, I have just noticed a bug with the JSDoc hint for
The type docs are not correct!
node.error should permit an optional 'error' parameter
Just to make sure I understand this correctly...
Is this summary better?
done() when the input message processing has finished succesfully, in case the input message is being processed asynchronously. When the message is being processed synchronously, Node-RED automatically detects when the processing is done.
done(err) when the input message processing has finished unsuccesfully due to a blocking error, i.e. when the message processing is interrupted and stopped. This should be used instead of the old
node.error(err) when there is a non-blocking error during the processing, i.e. when the message processing is not interrupted after the error. After that processing we arrive back at 1 or 2.
Perhaps just to add to #1 that done is only needed when doing async message processing/sending. It isn't needed if you are only sending a msg at the end of the function node code.
I have edited my post to add your remark.
Or like you english speaking people always say: "Consider it done"
Shouldn't that be "Consider it done()"
Damn you Julian. Now you have even confused me even more
- When I process a message synchronously, then the Complete node is automatically triggered by Node-RED as soon as the synchronous code is completed.
- When I process a message asynchronously, then I need to call
done() myself in my code because otherwise Node-RED doesn't know when the asynchronous code is completed.
However to be able to start the asynchronous code, I first need to run some synchronous code:
- I need to validate the message
- Then I need to enrich the message with some extra data
- Then I call the asynchronous function --> in which I need to call
- I do some postprocessing (e.g. change the node status, ...)
So how does Node-RED see the difference between synchronous processing of a message, and asynchronous processing (which is also started in the middle of a bunch of synchronous code)
Got a couple of days ago my first question ever about one of my nodes to make it compatible with the Complete node. So it would be very welcome to get some understanding in how this works, so I can refactor my node to accomplish this...
"Your mission, should you choose to accept it ..."
It doesn't need to and doesn't care. All
done() does is terminate the processing - or rather tells Node-RED that the processing has ended. You don't need to do that when running a straight synchronous function because the function has already ended - there is nothing for Node-RED to do.
When talking about custom nodes, it doesn't hurt to call done, I do that in uibuilder. Mostly because the processing is somewhat hybrid and calling done is safer than not calling it. Just as not calling it in a synchronous mode, calling when similarly in such a mode does no harm, it just isn't necessary. I don't do it in simpler nodes because the processing of the msg is more linear. But I could, without any harm done.
For synchronous processing it doesn't matter whether you call
done() at the end or not.:
Is equal to:
Because at the end of the synchronous processing, Node-RED knows automatically that the message processing has ended. That sounds logical
But for asynchronous processing:
--> Some time afterwards I need to call done() in the async function
How does Node-RED know in this case that the message processing is NOT completed after the sychronous code is finished. Because doPreProcessing and doPostProcessing is simple synchronous code that is completed, but the real message processing is not completed. In this case the message processing is only completed when I call
done() in the asynchronous function...
I think I am missing something very simple here...
Even for synchronous nodes I think that if the node can fail then it should call done, either showing success or failure. That allows the user to use Catch and Complete nodes, and know that one, and only one, of them will always be called.
I think that Julian meant not that NR automatically calls done() for you, just that there is no benefit to calling done() as messages pass straight through without delay.
Let me add another question.
From the above discussion, I was also expecting that
complete node should be called only when
node.done() is emitted. However, it gets called from every single
node.send(). Is that the correct behavior?
Sorry, but your question is quite ambiguous & I don't want to pass on bad info.
How many times in the function node is
node.send called is this particular scenario? By that I mean if you trigger the function ONCE, how many times is
Are you actually calling
node.done anywhere in this function node?
Can you share a minimal flow that demonstrates what you are seeing?
Sorry, after your message I've revisited my code and I confirm my mistake. Node complete is activated after node.done() call. thx and sorry