周末闲来无事,随便翻看了一下阮一峰老师的《ES6 标准入门》第 2 版,ps: 之前在阮一峰老师的官网看过电子版,感觉干货满满,所以就买了纸质版;当看到第 16 章第 4 节'Promise.prototype.catch()'时,遇到了一个小困惑,下面我们来一起看一下
首先,Promise.prototype.catch 方法是用来'捕获 Promise 回调函数中自然发生或主动抛出的错误',何为自然发生?何为主动抛出?
自然发生的错误:
- 1
- function a() {
- 2
- var x = 1;
- 3 console.log(x + y) 4
- }
- 5 6 a() // 'ReferenceError: y is not defined'
变量 y 未定义,所以运行时产生了错误,这就是自然发生的错误,我们没有做异常处理,即 try catch
主动抛出的错误:
- 1
- function a() {
- 2
- var x = 1;
- 3
- try {
- 4 console.log(x + y) 5
- } catch(err) {
- 6 console.log(err) 7
- }
- 8
- }
- 9 10 a() // 'ReferenceError: y is not defined'
意识到可能会有异常出现,我们就用 try catch 处理,那我们如何区分一个错误是否被捕获到了呢?很简单,就是看浏览器控制台的日志:
未捕获到的错误日志是红色的
捕获到的错误日志是黑色的
上面已经说了 Promise.prototype.catch 的作用,以及错误的相关知识,那么我究竟遇到了什么问题呢?咱们继续往下看
书上有这么一个示例:
- 1
- var promise = new Promise(function(resolve, reject) {
- 2
- throw new Error('test') 3
- }) 4 promise.
- catch(function(error) {
- 5 console.log(error) 6
- }) 7 // Error: test
那我们就手动实践一下吧
错误真的被捕获到了,欧耶,perfect!!突然我又想到 Promise 不是用来实现异步操作的吗?那我们就试试 ajax 吧,然后又意识到没有接口(主要是当时懒得找),那就用 SetTimeout 代替吧
代码:
- 1 new Promise(function(resolve, reject) {
- 2 3 // 异步方式抛出异常
- 4 setTimeout(function() {
- 5
- throw new Error('出错1') 6
- },
- 2000) 7 8 // 同步方式抛出异常
- 9
- throw new Error('出错2') 10
- }).
- catch(function(err) {
- 11 console.log(err) 12
- })
运行截图:
纳尼?!错误 1 没有被捕获?开玩笑呢,让我缓一缓,终于想到了:setTimeout 是在 Window 下执行的,记得不?上面的代码就相当于:
- 1 varclock =function () {
- 2setTimeout(function () {
- 3 throw newError('出错1')
- 4 })
- 5 }
- 6
- 7 newPromise(function (resolve, reject) {
- 8
- 9 // 异步方式抛出异常
- 10 clock()
- 11
- 12 // 同步方式抛出异常
- 13 throw newError('出错2')
- 14}).catch(function (err) {
- 15 console.log(err)
- 16})
当我们执行一个函数时,归根到底就是把函数体内代码拿到它被调用的地方执行;所以在上上个示例中,在 Promise 实例中只是启动了 setTimeout 定时器,之后定时器就和 Promise 实例完全没有关系了,因为它被交由 Window 对象了,所以定时器中抛出的异常没有想我们想象的被 Promise 示例捕获,而是未加处理,直接在控制台报错;怎么样?你是否已经理解,如果理解了,我们再巩固一下,看看下面的代码:
- 1 varclock =function () {
- 2setTimeout(function () {
- 3console.log(this=== window)
- 4 throw newError('出错1')
- 5 })
- 6 }
- 7
- 8 varfunc =function () {
- 9 throw newError('出错3')
- 10 }
- 11
- 12
- 13 newPromise(function (resolve, reject) {
- 14 // 异步方式抛出异常
- 15 clock()
- 16
- 17 // 执行window.func抛出异常
- 18 func()
- 19
- 20 // 同步方式抛出异常
- 21 throw newError('出错2')
- 22}).catch(function (err) {
- 23 console.log(err)
- 24})
这里错误 3 能不能被 catch 捕获呢?答案是:Yes
不要被迷惑呦!虽然 func 是在 Promise 示例外面定义的,但是它和错误 2 是抛出方式没两样儿
这就是我在学习 Promise 相关知识时遇到的一个小插曲,我不相信只有我一个人有这个经历,哈哈;关于 Promise 的其他知识这里不是没有介绍,而是丝毫没有介绍,不好意思,我又调皮了,主要是我觉得学习 ES6,看阮一峰老师的《ECMAScript 6 入门》就够了,好了,就到这里吧,祝大家周末愉快!!
来源: http://www.cnblogs.com/sampapa/p/6979260.html