使用await的Call/apply/bind函数

7

我需要使用基于回调的API,但我想保留我的异步函数。这就是为什么我尝试编写一个de-promisify函数:

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

然而,当我试图取消Promise化一个箭头函数时,它将无法工作,因为您无法将任何内容绑定到它:

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

有没有解决方法?

1
这与async await无关,而是箭头函数在某些方面与“常规”函数不同。即使它是同步的,这段代码也不会像那样工作:new Usual(() => { this.hello(); return false; }); - Thomas
箭头函数不能用作方法。除了不使用this关键字(例如var x = new Usual(() => x.hello())),没有其他办法,当然,如果Usual在返回实例之前调用该函数,则此方法将无效。 - Bergi
1
顺便说一下,你的 depromisify 函数有问题,当它第二次抛出错误时会运行回调两次。使用带有两个回调函数的 .then(…, …) 代替:function depromisify(fn) { return function(...args) { var cb = args.pop(); fn.apply(this, args).then(v => cb(null, v), e => cb(e)).catch(e => void e); }; } - Bergi
@Bergi 对于重复的问题我很抱歉,但是你在“throws a second time”方面具体想到了什么?阅读你提供的线程,似乎这不是一个等价的情况,fn不能抛出两次,除非包装器本身抛出异常并且没有对try...catch之外的值进行赋值。 - Misiur
翻译:哎呀,弄错了那句话。我的意思是:当回调函数在第一次调用时抛出异常时,它将再次运行回调函数。你的catch不应该处理来自cb的异常。 - Bergi
1个回答

6

没有解决方案。在这方面,箭头函数有一点特殊。

这里是文档的引用:

两个因素影响了箭头函数的引入:更短的函数和this的非绑定性。


我也是这么想的。除非有人提出了什么神奇的解决方案,否则我明天会接受这个答案,谢谢。 - Misiur
1
很抱歉带来这个坏消息。你能憋多久呢 :-) - Randy Casburn
1
@Misiur 用 eval 的黑魔法可以做任何事情。不过你可能不会喜欢它。 - Bergi
@Bergi https://jsfiddle.net/b2pe0zq0/ - 这很奇怪。 - Misiur
@Misiur,我会一直听从Bergi的意见,但我仍然得到了那个勾号!嘿嘿。 - Randy Casburn
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接