0

I have this code:

  function runAsync(fn: Function) {
    ret.count++;
    fn(function (err: Error) {
      err && console.error(err.stack || err);
      ret.count--;
      if (ret.count < 1) {
        ret.cb();
      }
    });
  }

  s.on(events.FATAL_TEST_ERROR, function (val: any) {

    runAsync(function (cb: Function) {

      db.serialize(function () {
        db.run('CREATE TABLE lorem (info TEXT)');

        let stmt = db.prepare('INSERT INTO lorem VALUES (?)');
        for (let i = 0; i < 10; i++) {
          stmt.run('Ipsum ' + i);
        }
        stmt.finalize();

        db.all('SELECT rowid AS id, info FROM lorem', function (err: Error, rows: Array<any>) {

          cb()
        });
      });

    });
  });

what's happening is that if the user wants to include asynchronous calls, they need to call the runAsync function, and then place their code in the function body that's passed to runAsync.

Is there any way I can make this more automatic so that the user has to worry less about conforming perfectly to the API?

My primary concern is that the runAsync function has to be called in the same tick as the call to the event handler. My other concern is that it's all too common for API users to forget to fire callbacks.

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • Callbacks are lower level and more generic – Alexander Mills Apr 03 '17 at 00:11
  • I will add important details that I forgot to mention in the op – Alexander Mills Apr 03 '17 at 00:11
  • But I will take your advice and create a promise variant of the above. If they pass a callback then use the cb interface, no cb and we use promise interface, standard stuff. – Alexander Mills Apr 03 '17 at 00:17
  • As I indicated in the last part of the question - what I want to do is somehow enforce that the call to runAsync is the first call in event handler function - is there some clever way to do that? I need to make sure runAsync is called in the same tick of the event loop. – Alexander Mills Apr 03 '17 at 00:18
  • Disagree on promises. The async library is more powerful than promises. RxJS and observables are also more powerful than promises. You are not talking to a fan of promises :) – Alexander Mills Apr 03 '17 at 03:21
  • Well right now the API function is just the callback from an event emitter. What I could do is pass in a subclass of event emitter, and create an onAsync method, which will call the runAsync function. – Alexander Mills Apr 03 '17 at 04:04
  • In this case I have to interop with event emitter api, using callbacks is more straightforward. In the end I have to flip a boolean and fire a callback. What I am doing here is allowing for asynchronous reporters. With Mocha we can only have synchronous reporters, but with Suman we can have async reporters. I havent fully expored, but if you havent used async.autoInject then you just don't know. I didn't discover async.autoInject until a month ago, super powerful stuff. – Alexander Mills Apr 03 '17 at 04:27
  • I wonder if the NPM sqlite3 library can handle promises – Alexander Mills Apr 04 '17 at 02:26
  • @jsfriend00 here is some interesting reading on promises - https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs – Alexander Mills Apr 05 '17 at 19:47
  • http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/promise.html – Alexander Mills Apr 05 '17 at 19:48
  • you will notice that both sqlite3 and selenium webdriver for JS both avoid promises and use a pretty clever approach to async code. – Alexander Mills Apr 05 '17 at 19:48

1 Answers1

2

Please consider to use promises: https://www.promisejs.org/

Dody
  • 608
  • 7
  • 19
  • read about promises here - https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs and here - http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/lib/promise.html – Alexander Mills Apr 05 '17 at 19:48