我想为Promise.catch()编写一个包装程序,该包装程序执行一些默认操作,例如记录日志,然后调用.catch()拒绝Promise。
我试图理解我在示例代码的这两个简单位之间所表现出的行为差异。
为什么不起作用:
declare global {
interface Promise<T> {
catchWrapper(): Promise<T>;
}
}
export {}
Promise.prototype.catchWrapper = function(){
return Promise.prototype.catch.apply(this, e => { console.log(`An error occured: {e}`) });
};
async function f(): Promise<string> {
throw new Error('error');
}
f().catchWrapper()
但是这样做:
declare global {
interface Promise<T> {
catchWrapper(errHandler: (errObj: any) => void): Promise<T>;
}
}
export {}
Promise.prototype.catchWrapper = function(){
return Promise.prototype.catch.apply(this, arguments);
};
async function f(): Promise<string> {
throw new Error('An error');
}
f().catchWrapper(e => { console.log(`An error occured: ${e}`) });
第一个示例是在catchWrapper内部创建lambda函数,此示例生成未处理的promise拒绝。
第二个示例在catchWrapper外部创建lambda并将其传递。这按预期工作。
我是否发现this
和lambda不兼容?
(我正在使用打字稿3.1.2和节点8.11.3)
修改: 第一个示例将arrow函数放置在数组内之后工作,如下所示:
return Promise.prototype.catch.apply(this,
[e => { console.log(`An error occured: ${e}`) }]);
答案 0 :(得分:2)
arguments
是一个参数数组。因此,在您的第二个示例中:
Promise.prototype.catchWrapper = function(){
return Promise.prototype.catch.apply(this, arguments);
};
您将参数作为数组传递,而不是像您期望的那样传递函数。您可以尝试传入arguments[0]
来获取该功能。
或者您可以使用传播运算符:
Promise.prototype.catchWrapper = function(){
return Promise.prototype.catch.apply(this, ...arguments);
};
但是简短的答案是您要传递一个参数数组,而不是将参数作为单独的参数。