我需要使用基于回调的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;
}));
有没有解决方法?
async await
无关,而是箭头函数在某些方面与“常规”函数不同。即使它是同步的,这段代码也不会像那样工作:new Usual(() => { this.hello(); return false; });
- Thomasthis
关键字(例如var x = new Usual(() => x.hello())
),没有其他办法,当然,如果Usual
在返回实例之前调用该函数,则此方法将无效。 - Bergidepromisify
函数有问题,当它第二次抛出错误时会运行回调两次。使用带有两个回调函数的.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); }; }
- Bergifn
不能抛出两次,除非包装器本身抛出异常并且没有对try...catch
之外的值进行赋值。 - Misiurcatch
不应该处理来自cb
的异常。 - Bergi