-
Notifications
You must be signed in to change notification settings - Fork 15
Open
@spivet
Description
本文不对 Promise 的基本用法和 API 做介绍,只是对一些进阶用法做总结。
异步函数中抛出的错误,无法被 catch
很多文章里都会说 reject() 与 throw 效果一样,这种说法并不完全正确。
如果在同步操作里用 throw 抛出错误,两者效果相同,但是如果在异步函数中抛出的错误,是无法被 catch 到的。
举个例子:
new Promise(function(resolve, reject) { setTimeout(function() { throw 'Uncaught Exception!' }, 100) }) .catch(function(err) { console.log('打印错误', err) // 不会执行 })
这段代码会抛出错误,但是 catch 函数里的代码并不会执行,换作 reject 则可以:
new Promise(function(resolve, reject) { setTimeout(function() { reject('Caught Exception!') }, 100) }) .catch(function(err) { console.log('打印错误', err) // 打印错误 Caught Exception! })
用 .catch() 捕获异常
.catch() 的作用与 then(resolved, rejected) 中 rejected 回调的作用几乎一致。但是 resolved 回调里抛出的错误在 rejected 是无法捕获的,所以尽量使用 .catch() 来进行错误捕获。
.then() 回调函数的返回值
在 .then() 的回调函数里通常会返回三种类型的值:
1. return 另一个 promise
var anotherPromise = function() { return Promise.resolve('bar') } Promise.resolve('foo') .then(function(value) { console.log(value) // foo return anotherPromise() }) .then(function(result) { console.log(`result is: ${result}`) // result is: bar })
2. return 一个同步的值 (如果没有明确返回值,会默认返回 undefined)
var anotherPromise = function() { return Promise.resolve('bar') } Promise.resolve('foo') .then(function(value) { console.log(value) // foo anotherPromise() return '同步值' }) .then(function(result) { console.log(`result is: ${result}`) // result is: 同步值 }) Promise.resolve('foo') .then(function(value) { anotherPromise() }) .then(function(result) { console.log(`result is: ${result}`) // result is: undefined })
3. throw 一个同步异常(不是返回值,但在这里把它当作返回值)
var anotherPromise = function() { throw 'oh error!' } Promise.resolve('foo') .then(function(value) { return anotherPromise() }) .catch(function(err) { console.log(`result is: ${err}`) // result is: oh error! })
Promise 穿透
.then(resolved, rejected) 中的参数 resolved rejected 必须是两个回调函数。
假如传的不是函数,而是直接调用函数,那么上一个 Promise 返回的值会跳过这个 then,直接到下一个。
function sayHello() { console.log('hello') } console.log('start') Promise.resolve('foo') .then(sayHello()) .then(function(result) { console.log(`result is: ${result}`) }) console.log('end') // 会依次打印 start hello end result is: foo
参考文章
Promise进阶
We have a problem with promises
Promise - JavaScript | MDN
Metadata
Metadata
Assignees
Labels
No labels