Skip to content

Commit

Permalink
added unwind and let whilst/until use it. Fix caolan#133
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed May 31, 2012
1 parent b01270d commit 851bb39
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 12 deletions.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ So far its been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:
* [iterator](#iterator)
* [apply](#apply)
* [nextTick](#nextTick)
* [unwind](#unwind)

### Utils

Expand Down Expand Up @@ -919,6 +920,42 @@ __Example__
});
call_order.push('one')

---------------------------------------

<a name="unwind" />
### unwind(function, callback)

Calls a asynchronous function. If the function is not really asynchronous, the
callback is not called, but `unwind` returns the arguments as result.

This is useful to prevent stack overflows in asynchronous loop with not really
asynchronous functions.

__Arguments__

* function - A function which should be called. `task(callback)`
* callback - The callback to call if the function is really asynchronous.

__Returns__

A Array containing the arguments passed from the task to the callback.
`unwind` only returns the array if task was synchronous.
If task is asynchronous `unwind` do not return anything.

__Example__

function may(callback) {
if (Math.random() < 0.5) {
setTimeout(callback.bind(null, "async"), 1000);
} else {
callback("sync");
}
}
var sync = async.unwind(may, console.log);
if (sync) { // only if may was synchronous
console.log(sync[0]);
}


## Utils

Expand Down
51 changes: 39 additions & 12 deletions lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,19 @@
wrapIterator(async.iterator(tasks))();
};

async.unwind = function(task, callback) {
var result;
var cb = function(err, value) {
result = Array.prototype.slice.call(arguments, 0);
};
task(function(err, value) { cb.apply(null, arguments); });
if (!result) {
cb = callback || function () {};
} else {
return result;
}
}

async.parallel = function (tasks, callback) {
callback = callback || function () {};
if (tasks.constructor === Array) {
Expand Down Expand Up @@ -550,31 +563,45 @@
async.concatSeries = doSeries(_concat);

async.whilst = function (test, iterator, callback) {
if (test()) {
iterator(function (err) {
while (test()) {
function iteratorCallback(err) {
if (err) {
return callback(err);
}
async.whilst(test, iterator, callback);
});
}
else {
callback();
}
var sync = async.unwind(iterator, iteratorCallback);
if (sync) {
if (sync[0]) {
return callback(sync[0]);
}
continue;
} else {
return;
}
}
callback();
};

async.until = function (test, iterator, callback) {
if (!test()) {
iterator(function (err) {
while (!test()) {
function iteratorCallback(err) {
if (err) {
return callback(err);
}
async.until(test, iterator, callback);
});
}
else {
callback();
}
var sync = async.unwind(iterator, iteratorCallback);
if (sync) {
if (sync[0]) {
return callback(sync[0]);
}
continue;
} else {
return;
}
}
callback();
};

async.queue = function (worker, concurrency) {
Expand Down

0 comments on commit 851bb39

Please sign in to comment.