mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Merge pull request #4332 from node-red/4330-fix-multiple-input-handlers
Handle nodes with multiple input handlers properly
This commit is contained in:
		| @@ -42,6 +42,7 @@ function Node(n) { | ||||
|     this._closeCallbacks = []; | ||||
|     this._inputCallback = null; | ||||
|     this._inputCallbacks = null; | ||||
|     this._expectedDoneCount = 0; | ||||
|  | ||||
|     if (n.name) { | ||||
|         this.name = n.name; | ||||
| @@ -159,6 +160,9 @@ Node.prototype.on = function(event, callback) { | ||||
|     if (event == "close") { | ||||
|         this._closeCallbacks.push(callback); | ||||
|     } else if (event === "input") { | ||||
|         if (callback.length === 3) { | ||||
|             this._expectedDoneCount++ | ||||
|         } | ||||
|         if (this._inputCallback) { | ||||
|             this._inputCallbacks = [this._inputCallback, callback]; | ||||
|             this._inputCallback = null; | ||||
| @@ -218,19 +222,17 @@ Node.prototype._emitInput = function(arg) { | ||||
|             } else if (node._inputCallbacks) { | ||||
|                 // Multiple callbacks registered. Call each one, tracking eventual completion | ||||
|                 var c = node._inputCallbacks.length; | ||||
|                 let doneCount = 0 | ||||
|                 for (var i=0;i<c;i++) { | ||||
|                     var cb = node._inputCallbacks[i]; | ||||
|                     if (cb.length === 2) { | ||||
|                         c++; | ||||
|                     } | ||||
|                     try { | ||||
|                         cb.call( | ||||
|                             node, | ||||
|                             arg, | ||||
|                             function() { node.send.apply(node,arguments) }, | ||||
|                             function(err) { | ||||
|                                 c--; | ||||
|                                 if (c === 0) { | ||||
|                                 doneCount++; | ||||
|                                 if (doneCount === node._expectedDoneCount) { | ||||
|                                     node._complete(arg,err); | ||||
|                                 } | ||||
|                             } | ||||
| @@ -257,6 +259,9 @@ Node.prototype._removeListener = Node.prototype.removeListener; | ||||
| Node.prototype.removeListener = function(name, listener) { | ||||
|     var index; | ||||
|     if (name === "input") { | ||||
|         if (listener.length === 3) { | ||||
|             this._expectedDoneCount-- | ||||
|         } | ||||
|         if (this._inputCallback && this._inputCallback === listener) { | ||||
|             // Removing the only callback | ||||
|             this._inputCallback = null; | ||||
|   | ||||
| @@ -183,6 +183,35 @@ describe('Node', function() { | ||||
|             n.receive(message); | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         it('calls parent flow handleComplete when multiple callbacks provided', function(done) { | ||||
|             var n = new RedNode({id:'123',type:'abc', _flow: { | ||||
|                 handleComplete: function(node,msg) { | ||||
|                     try { | ||||
|                         doneCount.should.equal(2) | ||||
|                         msg.should.deepEqual(message); | ||||
|                         done(); | ||||
|                     } catch(err) { | ||||
|                         done(err); | ||||
|                     } | ||||
|                 } | ||||
|             }}); | ||||
|  | ||||
|             var message = {payload:"hello world"}; | ||||
|             let doneCount = 0 | ||||
|             n.on('input',function(msg, nodeSend, nodeDone) { | ||||
|                 doneCount++ | ||||
|                 nodeDone(); | ||||
|             }); | ||||
|             // Include a callback without explicit done signature | ||||
|             n.on('input',function(msg) { }); | ||||
|             n.on('input',function(msg, nodeSend, nodeDone) { | ||||
|                 doneCount++ | ||||
|                 nodeDone(); | ||||
|             }); | ||||
|             n.receive(message); | ||||
|         }); | ||||
|  | ||||
|         it('triggers onComplete hook when done callback provided', function(done) { | ||||
|             var handleCompleteCalled = false; | ||||
|             var hookCalled = false; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user