Skip to content


Subversion checkout URL

You can clone with
Download ZIP


add callbacks for async chaining of tasks #1822

wants to merge 3 commits into from

4 participants


Right now, you're kind of screwed if you need to use async code in a subtask from cake. This branch adds an extra callback argument to invoke so that you can supply a completion callback to an asynchronous subtask.


You'll need to modify /src/ as well...


Oh, I'm an idiot. Yes.


All right, updated both the .coffee and the .js now.


I'm not sure this works as a solution, actually -- as long as there are existing invoke() calls that don't supply a callback, then it's still kind of a mess.


So, here's the deal with Cake -- it's just a tiny little shim for exposing your top-level CoffeeScript functions to the command-line:

... not a full-featured Rake-style library with dependency resolution, nested tasks, etc etc. The idea is that those things: composing multiple async events, determining the order in which a series of functions should be run, defining a complex API -- are all things better done in regular code, and not a wimpy DSL. Once you have your code sorted out, instead of stuffing all of the important reusable logic into Cake tasks, just expose the bits you want accessible to the command-line via Cake. Does that sound reasonable?


Yeah, I think that's pretty much how it has to work. Callbacks are pretty much an all-or-nothing thing in node. Node fail rather than cake fail I guess.

@mental mental closed this
@devongovett devongovett referenced this pull request

Tame #1942


Jeremy (or anyone who knows...), could you post an example of how to invoke a module that does async stuff from a Cakefile? I've tried code both in the Cakefile and in a separate .coffee module required by the Cakefile and either way my main process exits before my async code is done executing. I'm trying to use child_process.spawn to launch mocha tests.

@mahnunchik mahnunchik referenced this pull request

Cake 'invoke' callback #2733

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 21 additions and 7 deletions.
  1. +9 −3 lib/coffee-script/cake.js
  2. +12 −4 src/
12 lib/coffee-script/cake.js
@@ -20,7 +20,7 @@
oparse = null;
helpers.extend(global, {
- task: function(name, description, action) {
+ asyncTask: function(name, description, action) {
var _ref;
if (!action) {
_ref = [description, action], action = _ref[0], description = _ref[1];
@@ -31,12 +31,18 @@
action: action
+ task: function(name, description, action) {
+ return global.asyncTask(name, description, function(options, cb) {
+ action(options);
+ return cb();
+ });
+ },
option: function(letter, flag, description) {
return switches.push([letter, flag, description]);
- invoke: function(name) {
+ invoke: function(name, cb) {
if (!tasks[name]) missingTask(name);
- return tasks[name].action(options);
+ return tasks[name].action(options, cb || (function() {}));
16 src/
@@ -22,11 +22,19 @@ oparse = null
# Mixin the top-level Cake functions for Cakefiles to use directly.
helpers.extend global,
+ # Define an asynchronous Cake task with a short name, an optional sentence
+ # description, and the function to run as the action itself. The function
+ # takes an additional callback argument to call when it completes.
+ asyncTask: (name, description, action) ->
+ [action, description] = [description, action] unless action
+ tasks[name] = {name, description, action}
# Define a Cake task with a short name, an optional sentence description,
# and the function to run as the action itself.
task: (name, description, action) ->
- [action, description] = [description, action] unless action
- tasks[name] = {name, description, action}
+ global.asyncTask name, description, (options, cb) ->
+ action(options)
+ cb()
# Define an option that the Cakefile accepts. The parsed options hash,
# containing all of the command-line options passed, will be made available
@@ -35,9 +43,9 @@ helpers.extend global,
switches.push [letter, flag, description]
# Invoke another task in the current Cakefile.
- invoke: (name) ->
+ invoke: (name, cb) ->
missingTask name unless tasks[name]
- tasks[name].action options
+ tasks[name].action options, cb or (->)
# Run `cake`. Executes all of the tasks you pass, in order. Note that Node's
# asynchrony may cause tasks to execute in a different order than you'd expect.
Something went wrong with that request. Please try again.