Promise 是一个对象,表示异步操作的结果。它通常有三种状态,即pending、fulfilled、rejected,异步任务的结果好坏取决于pending最终变为fulfilled或rejected。
Promise 状态

Promise 是一个对象,表示异步操作的结果。它有一个 [[PromiseState]] 属性,表示当前的状态,状态有两种,即 pending 和 fulfilled 以及 rejected。

[JS]Promise_异步任务

在异步任务完成之前,Promise 的状态是 pending,即处于等待异步任务返回结果的状态中。

[[PromiseState]] 会根据异步任务完成的情况改变 fulfilled 或 rejected。异步任务成功时调用 resolve,并改变 Promise 的状态为 fulfilled ;失败时调用 reject,并改变 Promise 的状态为 rejected 。

[JS]Promise_异步操作_02

Promise 可以做什么?请转至[JS]回调函数和回调地狱 - 回调地狱一文,了解 Promise 能够解决什么问题。

resolve

resolve 即在异步任务成功时调用。它还可以携带一条成功消息给 then() 函数。

new Promise((resolve, reject) => {
    resolve('success')
}).then((r) => {
    console.log(r) // => 'success'
})
reject

reject 即在异步任务失败时调用。它可以携带一条错误消息给 then() 或者 catch() 函数。

new Promise((resolve, reject) => {
    reject('failed')
}).then(
    (r) => {},
    (e) => {
        console.log(e) // => 'failed'
    }
)
Promise 链

Promise 允许链式异步操作,无需把每个操作嵌套在前一个操作的回调内部,因此 Promise 可以解决回调地狱的问题。

function asyncFn() { 
    return new Promise((resolve, reject) => {
        resolve('success')
    })
}

asyncFn()
    .then((res) => {
        return asyncFn()
    })
    .then((res) => {
        return asyncFn()
    })
    .catch((error) => {
        console.log(error)
    })
all

Promise 提供的静态方法 all() 可以并行执行任意数量的 Promise。all() 会返回一个数组,数组元素是 Promise 的 [[PromiseResult]] 结果字符串。如果某个 Promise 调用了 reject ,那么就会立即结束,进入到 catch 异常捕获回调函数。

function asyncFn(bool) {
    return new Promise((resolve, reject) => {
        if (bool) {
            resolve('successed')
        } else {
            reject('failed')
        }
    })
}

Promise.all([asyncFn(true), asyncFn(true)])
    .then((res) => {
        console.log(res) // ["success", "success"]
    })
    .catch((error) => {
        console.log(error)
    })
allSettled

all() 与 allSettled() 也是可以并行执行任意数量的 Promise。但是与 all 不同的是,allSettled 不会因为一个 rejected 而立即结束。

Promise.allSettled([asyncFn(true), asyncFn(false), asyncFn(true)])
    .then((res) => {
        console.log(res)
    })
    .catch((error) => {
        console.log(error)
    })

allSettled() 会返回一个数组,数组的元素(对象字面量)的 status 和 value 属性对应着 Promise 的 [[PromiseState]] 和 [[PromiseResult]]。

[JS]Promise_数组_03

async/await

async 定义在函数上代表该函数为一个异步任务,它本质是一个 Promise。

async function asyncFn() {
    let result = await Promise.resolve('success')
    console.log(result) // => 'success'
    return result
}

[JS]Promise_数组_04

await 相当于 then(),如果直接 await 'success',系统会自动将内容封装到 Promise.resolve('success') 中。

打印函数,可以看到结果返回了一个 Promise 对象,[[PromiseState]] 为 fulfilled 说明异步任务执行成功。

async/await 是一个语法糖,与使用 new 关键字创建 Promise 本质上没有任何区别:

new Promise((resolve, reject) => {
    resolve(1)
}).then(res => {
    console.log(res)
})

对于 reject() 错误信息,需要使用 try/catch 捕获:

async function asyncFn() {
    let result = null
    try {
        result = await Promise.reject(new Error('error'))
    } catch (e) {
        console.error(e)
    }
    return result
}