你是否也在学习ES6 Promise时遇到过这个问题?
背景
周末闲来无事,随便翻看了一下阮一峰老师的《ES6 标准入门》第2版,ps:之前在阮一峰老师的官网看过电子版,感觉干货满满,所以就买了纸质版;当看到第16章第4节 'Promise.prototype.catch()'时,遇到了一个小困惑,下面我们来一起看一下
开胃汤
首先,Promise.prototype.catch方法是用来'捕获Promise回调函数中自然发生或主动抛出的错误',何为自然发生?何为主动抛出?
自然发生的错误:
function a() {
var x = 1;
console.log(x+y)
}
a() // 'ReferenceError: y is not defined'
变量y未定义,所以运行时产生了错误,这就是自然发生的错误,我们没有做异常处理,即try catch
主动抛出的错误:
function a() {
var x = 1;
try{
console.log(x+y)
}catch(err){
console.log(err)
}
}
a() // 'ReferenceError: y is not defined'
意识到可能会有异常出现,我们就用try catch处理,那我们如何区分一个错误是否被捕获到了呢?很简单,就是看浏览器控制台的日志:
未捕获到的错误日志是红色的

捕获到的错误日志是黑色的

正餐
上面已经说了Promise.prototype.catch的作用,以及错误的相关知识,那么我究竟遇到了什么问题呢?咱们继续往下看
书上有这么一个示例:
var promise = new Promise(function(resolve, reject){
throw new Error('test')
})
promise.catch(function(error){
console.log(error)
})
// Error: test
那我们就手动实践一下吧

错误真的被捕获到了,欧耶,perfect!!突然我又想到Promise不是用来实现异步操作的吗?那我们就试试ajax吧,然后又意识到没有接口(主要是当时懒得找),那就用SetTimeout代替吧
代码:
new Promise(function (resolve, reject) {
// 异步方式抛出异常
setTimeout(function () {
throw new Error('出错1')
},2000)
// 同步方式抛出异常
throw new Error('出错2')
}).catch(function (err) {
console.log(err)
})
运行截图:

纳尼?!错误1没有被捕获?开玩笑呢,让我缓一缓,终于想到了:setTimeout是在Window下执行的,记得不?上面的代码就相当于:
var clock = function () {
setTimeout(function () {
throw new Error('出错1')
})
}
new Promise(function (resolve, reject) {
// 异步方式抛出异常
clock()
// 同步方式抛出异常
throw new Error('出错2')
}).catch(function (err) {
console.log(err)
})
当我们执行一个函数时,归根到底就是把函数体内代码拿到它被调用的地方执行;所以在上上个示例中,在Promise实例中只是启动了setTimeout定时器,之后定时器就和Promise实例完全没有关系了,因为它被交由Window对象了,所以定时器中抛出的异常没有想我们想象的被Promise示例捕获,而是未加处理,直接在控制台报错;怎么样?你是否已经理解,如果理解了,我们再巩固一下,看看下面的代码:
var clock = function () {
setTimeout(function () {
console.log(this === window)
throw new Error('出错1')
})
}
var func = function () {
throw new Error('出错3')
}
new Promise(function (resolve, reject) {
// 异步方式抛出异常
clock()
// 执行window.func抛出异常
func()
// 同步方式抛出异常
throw new Error('出错2')
}).catch(function (err) {
console.log(err)
})
这里错误3能不能被catch捕获呢?答案是:Yes

不要被迷惑呦!虽然func是在Promise示例外面定义的,但是它和错误2是抛出方式没两样儿
结语
这就是我在学习Promise相关知识时遇到的一个小插曲,我不相信只有我一个人有这个经历,哈哈;关于Promise的其他知识这里不是没有介绍,而是丝毫没有介绍,不好意思,我又调皮了,主要是我觉得学习ES6,看阮一峰老师的《ECMAScript 6 入门》就够了,好了,就到这里吧,祝大家周末愉快!!
你是否也在学习ES6 Promise时遇到过这个问题?的更多相关文章
- 通过 ES6 Promise 和 jQuery Deferred 的异同学习 Promise
Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同.不过它们的作用可以简单的用两句话来描述 Deffered 触发 resolve ...
- es6 Promise 事件机制分析
最近在学习es6的Promise,其中涉及到了Promsie的事件执行机制,因此总结了关于Promise的执行机制,若有错误,欢迎纠错和讨论. 在阮一峰老师的书中<es6 标准入门>对Pr ...
- ES6 Promise 接口
构造函数 new Promise(function(resolve, reject){}); 构造函数接受一个函数(executor)作为参数,该函数在返回 Promise 实例之前被调用.函数的两个 ...
- Es6 Promise 用法详解
Promise是什么?? 打印出来看看 console.dir(Promise) 这么一看就明白了,Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方 ...
- ES6 Promise 全面总结
转载:点击查看原文 ES6 Promise对象 ES6中,新增了Promise对象,它主要用于处理异步回调代码,让代码不至于陷入回调嵌套的死路中. @-v-@ 1. Promise本质 Promise ...
- ES6 Promise 异步操作
最近越来越喜欢与大家进行资源分享了,并且及时的同步到自己的园子内,为什么呢? 一.小插曲(气氛搞起) 在上个月末,由于领导的高度重视(haha,这个高度是有多高呢,185就好了),走进了公司骨干员工的 ...
- 解析ES6 Promise
ES6 Promise 概念之类的,大概读者都应该有所知道,接下来我们直入终点. 先让我们来看看什么是Promise吧,他是一个object,类,arry,function? 首先,学习它的时候应该讲 ...
- ES6 Promise(2)
Promise的兴起,是因为异步方法调用中,往往会出现回调函数一环扣一环的情况.这种情况导致了回调金字塔的出现.不仅代码写起来费劲不美观,而且问题复杂的时候,阅读代码的人也难以理解. db.save( ...
- es6 promise 所见
一.Promise是什么? Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息:从本意上讲,它是承诺,承诺它过一段时间会给你一个结果. pro ...
随机推荐
- Java设计模式:代理模式(一)
问题的提出 现在生活中,常常在微信朋友圈里面看到代购的信息,你想在国外买什么,香港买什么,但是又懒得自己过去,于是常常委托别人帮忙买奶粉买那啥的.这类问题的缘由是因为客户和原产地没有直接的接触,所以需 ...
- Linux基础测试--11道题
000.创建一个目录/data mkdir /data 001.在/data 下面创建一个文件oldboy.txt touch /data/oldboy.txt 002.为oldboy.txt 增加内 ...
- MySQL注射的过滤绕过技巧
SQL注射的绕过技巧较多,此文仅做一些简单的总结. 最好利用的注射点: 支持Union 可报错 支持多行执行.可执行系统命令.可HTTP Request等额外有利条件 若非以上类型,则可能需要暴力猜解 ...
- Lambda表达式和Lambda表达式树
LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态. 为了富有效率的使用数据库和其他查询引擎,我们需要一种不同的方式表示管道中的各个操作.即把代码当作可在编程中进行检查的数据. Lambd ...
- nginx 高可用
1 nginx负载均衡高可用 1.1 什么是负载均衡高可用 nginx作为负载均衡器,所有请求都到了nginx,可见nginx处于非常重点的位置,如果nginx服务器宕机后端web服务将无法提供服务, ...
- android webview和 javascript 进行交互
HTML5进行app开发具有开发快,跨平台等优点,但是当客户需要访问照相机或者调用摄像头等硬件的时候,H5就会有限制,必须要调用原生方法进行设备访问.下面简要介绍JS和原生方法互相调用的方法: 1 在 ...
- 阿里react整合库dva demo分析
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px "Helvetica Neue"; color: #404040 } p. ...
- hdu4639 hehe 递推
此题为递推题 现场比赛中由于心态问题没能快速推出来定义f[i]为i个连续的he可以表示的语意的个数 则如果第i个he单独考虑f[i]=f[i-1];如果将第i个he和第i-1个he组合 则其只能表示为 ...
- java之反射
初学反射,也是第二次写博客了把,就简单记录一下. Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对 ...
- Tomcat--安装与部署(一)
一.Tomcat背景 自从JSP发布之后,推出了各式各样的JSP引擎.Apache Group在完成GNUJSP1.0的开发以后,开始考虑在SUN的JSWDK基础上开发一个可以直接提供Web服务的JS ...