metarhia / metasync

Asynchronous Programming Library for JavaScript & Node.js
https://metarhia.com
MIT License
205 stars 35 forks source link

Implement counter #403

Open tshemsedinov opened 5 years ago

tshemsedinov commented 5 years ago
const counter = metasync
  .count(5)
  .timeout(2000)
  .done(err => {
    /* timed out or done  */
  });
counter(4);
counter(-2);
counter(10);
// now value = 12 but > 5 and we will call 'done'

@nechaido please assign to somebody

KHYehor commented 5 years ago

As I understood, I should make method .count(a) as option and then make counter(b) anywhere I want. If b was less than a before async fn had finished it execution, done would be done with error. Correct me if I am not right, and I also can take this task.

KHYehor commented 5 years ago

What can you say about this implementation as example? I am not sure about callback done. What args should I pass to this fn and what way?

const timeout = (timeout, count, fn, callback) => {
  let finished = false;
  let curcount = 0;

  const timer = setTimeout(() => {
    finished = true;
    callback(new Error(FN_TIMEOUT));
  }, timeout);

  const sum = arg => {
    curcount += arg;
    if (count > curcount) return sum;
    finished = true;
    clearTimeout(timer);
    callback(); // done
    return null;
  };

  fn((...args) => {
    if (!finished) {
      clearTimeout(timer);
      finished = true;
      callback(...args);
    }
  });
  return sum;
};

const data = metasync.timeout(
  10000,
  5,
  callback => {
    setTimeout(() => {
      callback(null, 'someVal', 1, 2, 3, 4);
    }, 1000);
  },
  (err, res, ...args) => {
    if (err) console.error(err);
    else {
      console.log(res);
      console.log(args);
    }
  }
);

data(1);
data(1);
data(6); // there callback will be called but without args

// or I can make something like this

function Count(count) {
  this.count = count;
  this.curcount = 0;
  this.cb = null;
  this.to = null;
}

Count.prototype.timeout = function(to) {
  this.to = to;
  return this;
};

Count.prototype.done = function(fn) {
  this.cb = fn;
  const sum = arg => {
    this.curcount += arg;
    if (this.count > this.curcount) return sum;
    this.cb(/*...args*/);
    return null;
  };
  return sum;
};

const count = arg => new Count(arg);

const data = count(10)
  .timeout(2000)
  .done(err => {
    if (err) {
      /*...*/
    } else {
      /*...*/
    }
  });

data(4);
data(-10);
data(500); // callback here