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' 事件来解决。
promise-不使用catch出现warning的原因的更多相关文章
- Promise同时进入catch和then——踩坑
记录今天使用Promise遇到的一个坑--在resolve()返回运行then之后,函数又进入到了catch,源代码大意如下: var pro = function() { return new Pr ...
- 一些常见warning的原因和解决方法
在入职三周后,终于赶齐了接手项目落下两个月的项目,有了一些自己的空闲时间对项目进行整理.主要整理包括类目的整合,从原来一个系统文件夹下几百个文件整改为以MVC设计思想为原则的分文件夹整理类目,井然有序 ...
- 关于vuex和Promise reject 或.catch 的报错处理。
在我们开发过程中,经常会使用vuex来管理接口请求和返回数据. 在vue组件页面使用computed来读取vuex中state的数据. getTaskList({ commit }, payload) ...
- Promise的.then .catch
定义一个promise 调用promise 如果promise的状态为resolve 则 执行 .then 否则执行.catch 可以有多个.then 会按顺序执行 axios.post 可 ...
- Promise实例的catch方法
//Promise.prototype.catch方法是.then(null,rejection)的别名, //用于指定发生错误时的回调函数 //then方法指定的回调函数如果运行时抛出错误,也会被c ...
- Promise.then(a, b)与Promise.then(a).catch(b)问题详解
原文: When is .then(success, fail) considered an antipattern for promises? 问题 我在bluebrid promise FAQ上面 ...
- Vue 执行npm run dev时报了三个warning的原因
刚装上了win10,用vue运行下项目,输入npm run dev之后报了三个以下错误: There are multiple modules with names that only differ ...
- 6个Async/Await完胜Promise的原因
友情提醒:NodeJS自从7.6版开始已经内置了对async/await的支持.如果你还没用过该特性,那么接下来我会给出一系列的原因解释为何你应该立即开始使用它并且会结合示例代码说明. async/a ...
- Warning: Cannot modify header information原因及解决方案
相信大多数人在写PHP代码的时候,都遇到过类似"Warning: Cannot send session cookie – headers already sent…“或者”Cannot a ...
随机推荐
- JS截取字符串substr 和 substring方法的区别
substr 方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.substr(start [, length ]) 参数 stringvar 必选项.要提取子字符串的字符串文字或 ...
- AJAX 基本结构 数据加载
AJAX -- 网页数据异步加载 .ashx 一般处理程序 json 数据格式,在不同的语言之间传递数据 对象格式: "{"key":"value& ...
- oracle与mysql
『创业团队最佳选择是Oracle+MongoDB,而不是MySQL』,当深蓝在QQ群里抛出这样的观点的时候,就像是在马蜂窝里丢了一串鞭炮一样热闹起来. 创业者甲: 开什么玩笑,Oracle要收钱的,太 ...
- JSONP和HttpClient的区别
JSONP的特点: 1>JSONP可以解决主流浏览器的跨域问题 2>需要通过三步实现跨域/javascript-src开放策略/回调函数/数据封装 3>JSONPqingqiu是游浏 ...
- quartz部署出现找不到表的情况,错误提示: Table 'heart_beat.QRTZ_LOCKS' doesn't exist
描述一下,本地可以,部署到Linux就不行,Linux上的数据库是本地直接拷贝上去的,项目环境是Spring Boot2.1.Shiro.MyBatis.Redis.swagger.Bootstrap ...
- Does the C standard guarantee buffers are not touched past their null terminator?
Question: In the various cases that a buffer is provided to the standard library's many string funct ...
- 漫画|你还记得原生的JDBC怎么连接数据库吗?
数据表的设计范式 在实际开发中最为常见的设计范式有三个: 第一范式是最基本的范式.如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式: 第二范式需要确保数据库表中的每一列都 ...
- ViewModel处理View相关事件的多种方式(非技术贴,仅学习总结)
众所周知,在UWP中,微软为我们提供了一种新的绑定方式:x:bind,它是基于编译时的绑定.在性能方面,运行时绑定Binding与它相比还是有些逊色的.因此针对一些确定的.不需要变更的数据,我们完全有 ...
- [简记] fetch API 的初步使用
var myHeaders = new Headers(); myHeaders.append('Content-Type', 'application/x-www-form-urlencoded; ...
- git命令详解( 三 )
此篇为git命令的第三篇 目录 git Pull 模拟团队合作 Git Pull 在上一篇的结尾我们已经知道了如何用 git fetch 获取远程的数据, 现在我们学习如何将这些变化更新到我们的工作当 ...