Callback Set
Description:
When you're trying to write non-blocking code, you often end up with a number of asyncronous calls you want to send off, when do something when they are all complete. For example, deleting a number of files, then telling the user the operation is complete.
Your task is to create a simple function that will help with all that.
CreateCallbackSet(callback, args...)
The function should accept an optional arguments, callback
. If passed in, it should be set in the 'oncomplete' property of the returned object.
If more than 1 argument was passed in, the remaining arguments should be passed to the oncomplete callback when the set is complete.
An object should be returned with a number of properties:
instance.add(callback, args...)
The specified callback should be attached to the set. A new function should be returned for the caller to use as a callback for whatever async method they want to trigger. When the async method returns to this special callback, the original callback passed in should be called, with any arguments received from the async method passed along. It will also call intance.resolve() (see below).
If the callback passed in was not a function, an error should be thrown.
If further arguments were passed in to .add()
when the callback was attached, these arguments should be added to the end of the arguments passed to the callback.
instance.count
A number, starting at 0, indicating the number of added "trigger" callbacks that have not yet returned (been called). This does not include the original callback.
instance.resolve()
The instance.count
is decreased by 1. If count is now 0, instance.oncomplete
is called, if it has been set. Then all properties on the instance object should be removed (set to a nully value, or deleted).
When an added "trigger" callback has been called, instance.resolve
is called automatically, after the callback has run.
NOTE: .add()
or .resolve()
could be called by a callback, or even from outside the callbacks altogether. .oncomplete
could be changed outside of calling the CreateCallbackSet()
function. .count
could be changed to a non-number value, or a non-positive value (in which case, anything goes; just don't throw an error). All of these will have to be taken into account.
Some code examples:
var flow = "[";
var instance = CreateCallbackSet(function(end) {
flow += end;
}, "]");
instance.count === 0;
function step(val) {
flow += val;
}
var _1 = instance.add(step, "a");
instance.count === 1;
var _2 = instance.add(step, "b");
instance.count === 2;
var _3 = instance.add(step, "c");
instance.count === 3;
var _4 = instance.add(step, "d");
instance.count === 4;
_3();
/* automatically resolved */
instance.count === 3; flow === "[c";
_1();
/* automatically resolved */
instance.count === 2; flow === "[ca";
_2();
/* automatically resolved */
instance.count === 1; flow === "[cab";
_4();
/* automatically resolved */
instance.count === 0; flow === "[cabd";
/* instance.oncomplete called */
flow === "[cabd]";
// object nulled-out
!instance.oncomplete && !instance.add && !instance.resolve && !instance.count;
Similar Kata:
Stats:
Created | Aug 14, 2014 |
Published | Aug 14, 2014 |
Warriors Trained | 125 |
Total Skips | 51 |
Total Code Submissions | 299 |
Total Times Completed | 14 |
JavaScript Completions | 14 |
Total Stars | 5 |
% of votes with a positive feedback rating | 63% of 4 |
Total "Very Satisfied" Votes | 2 |
Total "Somewhat Satisfied" Votes | 1 |
Total "Not Satisfied" Votes | 1 |
Total Rank Assessments | 6 |
Average Assessed Rank | 5 kyu |
Highest Assessed Rank | 4 kyu |
Lowest Assessed Rank | 6 kyu |