优缺点对比:
发展史 | 优点 | 缺点 |
---|---|---|
Callback | 解决了同步问题 | 回调地狱、可读性差、无法 try / catch 、无法 return |
Promise | 一定程度上解决了回调地狱的可读性 | 无法取消、任务多时,同样存在语义不清晰 |
Generator | 可以控制函数的执行,可以配合 co 函数库使用 | 流程管理却不方便(即何时执行第一阶段、何时执行第二阶段 |
async / await | 语义更清晰、简洁,内置执行器 | 认知不清晰可能会造成大量 await 阻塞(程序并不会等在原地,而是继续事件循环,等到响应后继续往下走)情况 |
let promise = new Promise(function (resolve, reject) {
// code
})
promise
.then(() => {
// then
})
.catch((error) => {
// console.log(error)
})
.finally((_) => {
// finally
})
code
处是用于执行的代码,当new Promise
创建时,自动执行。
then
是定义在Promise.prototype
上的用来处理状态改变时的回调函数。
参数resolve
和reject
是 JavaScript 自身提供的回调函数。当code
呗执行后应该调用resolve
或reject
resolve
任务成功返回 valuereject
任务失败返回error
当promise
被reject
的时候或者运行代码抛出错误异常如:throw new Error('Whoops!')
,catch
负责处理错误
finaylly
是promise
结束时,无论结果是fulfilled
还是rejected
都会执行的回调函数
内部属性:
state
初始值pending
,resolve
的时候为fullfilled
,reject
的时候为rejected
result
初始值undefined
,resolve
的时候为value
,reject
的时候为error
对象执行多个 promise,并等待所有 promise 准备就绪,任意一个 promise 被 reject,都会立即出发 Promise.all 的 reject 并且返回该 promise 的 error
let promise = Promise.all([
/*promises*/
])
// 例子
let urls = [
'https://api.github.com/users/iliakan',
'https://api.github.com/users/remy',
'https://api.github.com/users/jeresig'
]
// 将每个 url 映射(map)到 fetch 的 promise 中
let requests = urls.map((url) => fetch(url))
// Promise.all 等待所有任务都 resolved
Promise.all(requests).then((responses) =>
responses.forEach((response) => alert(`${response.url}: ${response.status}`))
)
与 Promise.all 不同的是,Promise.allSettled 会等待所有 promise 完成,无论成功失败。
{status:"fulfilled", value:result}
对于成功的响应{status:"rejected", reason:error}
对于 error。只要有一个准备就绪就返回其结果或者错误
Promise.race([
new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
new Promise((resolve, reject) =>
setTimeout(() => reject(new Error('Whoops!')), 2000)
),
new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).then(alert) // 1
与 Promise.race 类似,Promise.any 等待的是第一个fulfilled
,如果都rejected
,则返回一个 error 数组
Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。
async 会将其后面的函数的返回值封装成一个Promise
对象,而 await 会等待这个Promise
完成,并将其结果返回。
async function hello() {
return (greeting = await Promise.resolve('Hello'))
}
hello().then(alert)
错误处理
try...catch
捕获 async/await 运行程序中抛出的错误