Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

必须知道的 Promise 进阶点(一) #18

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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

        AltStyle によって変換されたページ (->オリジナル) /