promise-不使用catch出现warning的缘由

今天在使用node运行js文件时,返回了下面的错误和警告,警告部分主要是由于使用了promise,可是没有使用catch来捕捉错误.
更详细的解释在下面,这是nodejs文档的process模块的一部分
用户deMBP:loveToken 用户$ node test.js
{ Error: connect ECONNREFUSED 10.240.100.88:8081
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:14)
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '10.240.100.88',
  port: 8081 }
(node:3718) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 10.240.100.88:8081
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:14)
(node:3718) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:3718) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.


'rejectionHandled' 事件——异步
若是有 Promise 被 rejected,而且此 Promise在 Node.js 事件循环的下次轮询及以后期间,被绑定了一个错误处理器(即便用了catch的话,就会触发这个事件)(例如使用 promise.catch()),会触发 'rejectionHandled' 事件。
此事件监听器的回调函数使用 rejected 的 Promise 引用,做为惟一入参。
Promise 对象应该已经在 'unhandledRejection' 事件触发时被处理,可是在被处理过程当中得到了一个 rejection 处理器。
对于 Promise 链,没有概念代表在 Promise 链的哪一个地方,全部的 rejection 老是会被处理。 因为原本就是异步的,一个 Promise rejection 能够在未来的某个时间点被处理-可能要远远晚于 'unhandledRejection' 事件被触发及处理的时间。
另外一种表述的方式就是,与使用同步代码时会出现不断增加的未处理异常列表不一样,使用 Promise 时,未处理异常列表可能会出现增加而后收缩的状况。
在同步代码状况下,当未处理异常列表增加时,会触发 'uncaughtException' 事件。
在异步代码状况下,当未处理异常列表增加时,会触发 'unhandledRejection' 事件,当未处理列表收缩(就是被解决了)时,会触发 'rejectionHandled' 事件。
例如:
const unhandledRejections = new Map();
process.on('unhandledRejection', (reason, p) => {//未处理
  unhandledRejections.set(p, reason);
});
process.on('rejectionHandled', (p) => {//已处理
  unhandledRejections.delete(p);
});
在上述例子中,unhandledRejections 会随着时间增长和缩减,代表 rejection 开始是未被处理状态,而后变成已处理状态。 能够定时(对于需长期运行的应用,这个多是最好的方式)或当进程结束时(对脚本的应用多是最方便的),在错误日志中记录这些错误信息。
'uncaughtException' 事件——同步
若是 Javascript 未捕获的异常,沿着代码调用路径反向传递回事件循环,会触发 'uncaughtException' 事件。 Node.js 默认状况下会将这些异常堆栈打印到 stderr 而后进程退出。 为 'uncaughtException' 事件增长监听器会覆盖上述默认行为。
'uncaughtException' 事件监听器的回调函数,使用 Error 对象做为惟一参数值。
例如:
process.on('uncaughtException', (err) => {
  fs.writeSync(1, `捕获到异常:${err}\n`);
});

setTimeout(() => {
  console.log('这里仍然会运行。');
}, 500);

// 故意调用一个不存在的函数,应用会抛出未捕获的异常。
nonexistentFunc();
console.log('这里不会运行。');
注意:正确地使用 uncaughtException
须要注意,若是打算使用 'uncaughtException' 事件做为异常处理的最后补救机制,这是很是粗糙的设计方式。 此事件不该该看成 On Error Resume Next(出了错误就恢复让它继续)的等价机制。 未处理异常自己就意味着应用已经处于了未定义的状态。若是基于这种状态,尝试恢复应用正常进行,可能会形成未知或不可预测的问题。
此事件的监听器回调函数中抛出的异常,不会被捕获。为了不出现无限循环的状况,进程会以非零的状态码结束,并打印堆栈信息。
若是在出现未捕获异常时,尝试去恢复应用,可能出现的结果与电脑升级时拔掉电源线出现的结果相似 -- 10次中有9次不会出现问题,可是第10次可能系统会出现错误。
正确使用 'uncaughtException' 事件的方式,是用它在进程结束前执行一些已分配资源(好比文件描述符,句柄等等)的同步清理操做。 触发 'uncaughtException' 事件后,用它来尝试恢复应用正常运行的操做是不安全的。
想让一个已经崩溃的应用正常运行,更可靠的方式应该是启动另一个进程来监测/探测应用是否出错, 不管 uncaughtException 事件是否被触发,若是监测到应用出错,则恢复或重启应用。

'unhandledRejection' 事件——异步
若是在事件循环的一次轮询中,一个 Promise 被 rejected,而且此 Promise 没有绑定错误处理器(就是没有对它进行处理的操做),’unhandledRejection 事件会被触发。 当使用 Promise 进行编程时,异常会以 "rejected promises" 的形式封装。Rejection 能够被 promise.catch() 捕获并处理,而且在 Promise 链中传播。'unhandledRejection 事件在探测和跟踪 promise 被 rejected,而且 rejection 未被处理的场景中是颇有用的。
此事件监听器的回调函数被传递以下参数:
    •    reason <Error> | <any> 此对象包含了 promise 被 rejected 的相关信息(一般是一个 Error 对象)。
    •    p 被 rejected 的 promise 对象。
例如:
process.on('unhandledRejection', (reason, p) => {
  console.log('未处理的 rejection:', p, '缘由:', reason);
  // 记录日志、抛出错误、或其余逻辑。
});

somePromise.then((res) => {
  return reportToUser(JSON.pasre(res)); // 故意输错 `pasre`。
}); // 没有 `.catch` 或 `.then`。
以下代码也会触发'unhandledRejection'事件
function SomeResource() {
  // 将 loaded 的状态设置为一个 rejected promise。
  this.loaded = Promise.reject(new Error('错误信息'));
}

const resource = new SomeResource();
// resource.loaded 上没有 .catch 或 .then。
在例子中,能够像在其余 'unhandledRejection' 事件的典型场景中同样,跟踪开发者错误致使的 rejection。 为了解决这样的错误,resource.loaded 中能够加一个不作任何操做的 .catch(() => { }) 处理器, 这样能够阻止 'unhandledRejection' 事件的触发。或者也可使用 'rejectionHandled' 事件来解决。

node

相关文章
相关标签/搜索