Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call/apply/bind with await [duplicate]

I have to work with a callback based API, but I would like to retain my async functions. That's why I'm trying to write a depromisify function:

const depromisify = fn => {
  if (!(fn[Symbol.toStringTag] === 'AsyncFunction')) {
    return fn;
  }

  // Can be `async` as the caller won't use assignment to get the result - it's all bound to the `cb`
  return async function () {
    const args = [...arguments];
    const cb = args.pop();

    try {
      return cb(null, await fn.apply(this, args));
    } catch (e) {
      return cb(e);
    }
  };
};

const normal = function(cb) {
  this.hello();
  cb(null, true);
};

const promised = async function() {
  this.hello();
  return true;
};

function Usual(fn) {
  this.random = 'ABC';
  fn.call(this, (err, result, info) => {
    console.log((err && err.message) || null, result);
  });
};

Usual.prototype.hello = () => {
  console.log('hello!');
};

new Usual(normal);
new Usual(depromisify(promised));

However it won't work when I try to depromisify an arrow function, as you can't bind anything to it:

new Usual(depromisify(async () => {
  this.hello();
  return false;
}));

Is there a solution for this?

like image 949
Misiur Avatar asked May 15 '18 19:05

Misiur


1 Answers

Nope. No solution. Arrow functions are a bit special in that regard.

Here is the quote from the docs:

Two factors influenced the introduction of arrow functions: shorter functions and non-binding of this.

like image 98
Randy Casburn Avatar answered Nov 08 '22 11:11

Randy Casburn