Skip to content

Commit 48d8500

Browse files
committed
Added description for bonus question
1 parent 542e90b commit 48d8500

File tree

1 file changed

+78
-2
lines changed

1 file changed

+78
-2
lines changed

2013-02-03-assignment.md

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,85 @@ A memoizer should be kept that is initialized to the value of the `seed`, and th
127127

128128
## [Bonus] Async Waterfall
129129

130+
Nested callback functions can get out of hand extremely quickly. There have been many attempts to solve this through different forms of control flow. One popular solution is the [async.js][] library. This library, in addition to providing some utility tools for collections and memoization, provides many useful control flow constructs. One of which is [`waterfall`][waterfall]. This function will run a series of callback functions, called tasks, consecutively (not in parallel), and it also allows you to pass arguments to the next tasks. Note that the structure of each task looks like the following:
131+
132+
```javascript
133+
// there can by any number of arguments,
134+
// but the last argument must be a reference to the next task
135+
function (arg1, arg2, ..., callback) {
136+
// perform task
137+
callback(null, 'foo', 'bar'); // call the next task
138+
// if the first argument is not falsy, an error occured,
139+
// and you should directly call the final callback with the error
140+
}
141+
```
142+
143+
In addition, the `waterfall` function is given a final `callback` function that should be called after the last task finishes. This callback will have a signature of:
144+
145+
```javascript
146+
function (err, arg1, arg2, ...) {
147+
}
148+
```
149+
150+
Because asynchronous tasks often result in some sort of error (poor connections, etc.), the `waterfall` function provides a means of breaking out early. The first argument when calling the callback should be falsy (usually null) if no error has occured. If that value ends up being truthy, however, then the `waterfall` implementation should directly call the final callback with the error value (the first parameter). So, the `waterfall` function should have the following signature:
151+
152+
```javascript
153+
/**
154+
* @param tasks is an array of functions
155+
* @param callback is the final function
156+
*/
157+
function waterfall(tasks, callback) {
158+
// ...
159+
}
160+
```
161+
162+
This will hopefully be much clearer with some examples:
163+
164+
```javascript
165+
// example with non-erroring tasks
166+
waterfall([
167+
// the first task will always have the signature function (callback)
168+
function (callback) {
169+
// do stuff
170+
callback(null, 'one', 'two');
171+
},
172+
function (arg1, arg2, callback) {
173+
callback(null, arg1 + '1', arg2 + '2');
174+
}
175+
], function (err, result1, result2) {
176+
// usually it is not idiomatic to return multiple result parameters;
177+
// however, we want to show that it is possible
178+
console.log(err, result1, result2); // > null "one1" "two2"
179+
});
180+
181+
// example with an erroring tasks
182+
waterfall([
183+
function (callback) {
184+
if (true) {
185+
// uh-oh, I error out
186+
callback("oh nooooez");
187+
} else {
188+
callback(null, 'would otherwise be foo');
189+
}
190+
},
191+
// the second task should never be called
192+
function (foo, callback) {
193+
console.log("I'm never called");
194+
callback(null, foo + 'bar');
195+
}
196+
], function (err, result) {
197+
// usually it is not idiomatic to return multiple result parameters;
198+
// however, we want to show that it is possible
199+
console.log(err, result); // > "oh nooooez" undefined
200+
});
201+
```
202+
203+
### Hint
130204

131205
<!-- links -->
206+
[async.js]: https://github.com/caolan/async
132207
[enumerable]: http://ruby-doc.org/core-1.9.3/Enumerable.html
133-
[underscore]: http://underscorejs.org
134-
[issues]: https://github.com/Duke-PL-Course/JavaScript/issues?state=open
135208
[help]: https://help.github.com/articles/fork-a-repo
209+
[issues]: https://github.com/Duke-PL-Course/JavaScript/issues?state=open
210+
[underscore]: http://underscorejs.org
211+
[waterfall]: https://github.com/caolan/async#waterfall

0 commit comments

Comments
 (0)