In the mean-time, you could implement an asynchronous semaphore. function Semaphore(callback, initial, context) { this.lock = initial || 0; this.callback = callback; this.context = context || callback; this.args = arguments.slice(3); } Semaphore.prototype = { v: function() { this.lock++; }, p: function() { var parameters; this.lock--; if (this.lock === 0 && this.callback) { // allow sem.p(arg1, arg2, ...) to override args passed to Semaphore constructor if (arguments.length > 0) { parameters = arguments; } else { parameters = this.args; } this.callback.apply(context, parameters); } } }; on('chat:message', function(msg) { // ... var sem = new Semaphore(function() { // does not need to be inline // ... }, 2); // supplying number of planned async operations means you don't need to call v() for each sendChat('', firstMessage, function(ops) { // ... sem.p(); }); sendChat('', secondMessage, function(ops) { // ... sem.p(); }); }); You don't have a guarantee what order the two sendChat calls execute, but you do have a guarantee that both have completed before the semaphore's callback fires. Of course, if you're only making one call to sendChat, you can simply call the function that would have been your callback directly (or put that code into the sendChat).