为什么console.error是一个方法而不是函数

Why is console.error a method instead of a function?

本文关键字:方法 一个 函数 console error 为什么      更新时间:2023-09-26

这些天我大量使用ES6 Promises。因此,如果不指定onRejected函数,则很容易丢失对异常的跟踪:

new Promise(function(resolve, reject) {
  resolve(doCrazyThingThatMightThrowAnException());
}).then(function(result) {
  return performDangerousTranformation(result);
});

如果我能使用catch()添加几个字节,以确保控制台中出现异常,那就太好了:

new Promise(function(resolve, reject) {
  resolve(doCrazyThingThatMightThrowAnException());
}).then(function(result) {
  return performDangerousTranformation(result);
}).catch(console.error);

不幸的是,这并不起作用,因为console.error是一个方法而不是一个函数。也就是说,在调用console.error()时,需要指定接收方console。您可以在浏览器控制台中很容易地验证这一点:

> console.error('err');
prints err
> var f = console.error;
> f('err');
throws Illegal invocation exception

这意味着添加我的catch()处理程序有点冗长:

new Promise(function(resolve, reject) {
  resolve(doCrazyThingThatMightThrowAnException());
}).then(function(result) {
  return performDangerousTranformation(result);
}).catch(function(error) { console.error(error); });

诚然,它在ES6:中要好一点

new Promise(function(resolve, reject) {
  resolve(doCrazyThingThatMightThrowAnException());
}).then(function(result) {
  return performDangerousTranformation(result);
}).catch((error) => console.error(error));

但最好避免额外的打字。更糟糕的是,如果你今天使用catch(console.error),你的异常会被默默地忽略,这正是你试图解决的问题!console.error()的工作原理有什么基础吗?它需要成为一种方法吗?

节点中的此行为似乎已更改:https://github.com/nodejs/node/commit/025f53c306d91968b292051404aebb8bf2adb458.

如果你的宗教允许,你可以扩展Promise对象:

Promise.prototype.catchLog = function() {
    return this.catch(
        function(val) {
            console.log("Promise has rejected with reason", val);
            throw val;          // continue with rejected path
        }
    );
};

然后

function crazy() { throw 99; }
Promise.resolve()
    .then(crazy)
    .catchLog();
>>> Promise has rejected with reason 99 

您要求能够添加"几个字节"的拒绝日志记录;它是catch末端的三个(L-o-g)。