<commit_before><commit_msg>Added intial version of promises, without support for exceptions<commit_after>// A deferred is a value that can be resolved at a later time.
// The value can be observed via the promise object
function Deferred()
{
  var value = undefined;
  var isDone = false;
  var doneCallbacks = [];
  var promise = new Promise();

  promise.onDone = function (cb)
  {
    if (typeof cb !== "function")
      throw new Error("Callback is not a function");

    doneCallbacks.push(cb);
  }

  promise.isDone = function ()
  {
    return isDone;
  }

  this.done = function (val)
  {
    if (isDone)
      throw new Error("Deferred is already done");

    value = val;
    isDone = true;

    for (var i = 0, l = doneCallbacks.length; i < l; i++)
    {
      try
      {
        doneCallbacks[i](value);
      }
      catch (_)
      {
        // ignore exception, other callbacks might still have to be called
      }
    }

    // these can be GC'ed now
    doneCallbacks = null;

    // now that value is available, callbacks can be called immediately
    promise.onDone = function (cb)
    {
      if (typeof cb !== "function")
        throw new Error("Callback is not a function");

      cb(value);
    }
  }

  this.promise = function ()
  {
    return promise;
  }

  this.toString = function ()
  {
    return "Deferred";
  }
}

// A promise is a value that may not be available yet.
// Use onDone to get called back when value is available.
function Promise()
{
}

{'fraction_non_alphanumeric': 0.10490921318090114, 'fraction_numerical': 0.0006724949562878278, 'mean_word_length': 2.358916478555305, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '865764', 'n_tokens_mistral': 454, 'n_tokens_neox': 443, 'n_words': 164}