Beta

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;
Fundamentals

Similar Kata:

Stats:

CreatedAug 14, 2014
PublishedAug 14, 2014
Warriors Trained125
Total Skips51
Total Code Submissions299
Total Times Completed14
JavaScript Completions14
Total Stars5
% of votes with a positive feedback rating63% of 4
Total "Very Satisfied" Votes2
Total "Somewhat Satisfied" Votes1
Total "Not Satisfied" Votes1
Total Rank Assessments6
Average Assessed Rank
5 kyu
Highest Assessed Rank
4 kyu
Lowest Assessed Rank
6 kyu
Ad
Contributors
  • wthit56 Avatar
  • Voile Avatar
Ad