1. JavaScript 基础

  2. 函数进阶

  3. 深入数据和类型

  4. 运算符

  5. 浏览器存储

  6. Document

  7. Web API

  8. 事件

  9. 错误处理

  10. 异步编程

  11. 网络请求

  12. 模块

  13. 练习

  14. 实例

  15. 工具与规范

在回调的章节中,我们使用回调函数来接收执行的结果。很多时候,我们的需求都是固定的,我们需要获知执行状态,执行结果要不成功要不失败。因此 JavaScript 提供了 Promise 对象让来封装了这些相关的属性和方法。

语法如下:

let promise = new Promise(function(resolve, reject) {
  // resolve 执行成功调用
	// reject 执行失败调用
});

我们改写一下上节课回调的例子:

$$jsdemo$$
$$edit$$
function sum(x, y) {
    return x + y
}

function doAfter3s(func) {
    // 三秒后执行的函数

    return new Promise(function (resolve, reject) {
        setTimeout(() => {
            // 接收执行结果
            // 并传递给回调函数
            let result = func()

            // 执行成功调用
            resolve(result)
        }, 3000)
    })
}

function callback(result) {
    // 定义的回调函数
    alert("任务执行完成")
    alert("执行结果:" + result)
}

let promise = doAfter3s(() => sum(5, 6))
promise.then(callback)

alert("结束执行") // 同步执行

我们把回调函数作为 then 的第一个参数。而此时,这个回调函数会成为 Promise 函数中的第一个参数 resolve

当代码执行成功调用 resolve 时就相当于调用了 then 中传递的回调函数。

Promise 接收一个函数,函数有两个参数 resolve、reject:

  • resolve:应在任务执行成功时调用。
  • reject:应在任务执行失败时调用。

then、catch、finally

Promise 有三个方法,then、 catch、 finally,可供我们传递回调函数来处理执行结果。

then

then 可以接收两个函数作为参数,分别处理 resolve 和 reject 的结果,语法如下:

promise.then(
    function (result) {
        /* 处理执行成功的结果 */
    },
    function (error) {
        /* 处理执行失败的结果 */
    }
)

catch

catch 接收一个函数作为参数,用以处理执行失败的结果,语法如下:

promise.catch(function (error) {
    /* 处理执行失败的结果 */
})

当然,这跟我们设置 then 的第一个参数为 null,只设置第二个参数等价的:

promise.then(
    null, 
    function (error) {
    /* 处理执行失败的结果 */
})

finally

不管执行成功还是执行失败都会被执行。

promise.finally(
    function () {
    /* 总是会执行 */
})

Promise 链

promise 的回调中 return 的值会作为下一个 then 中的参数,这便被称为 Promise 链。

$$jsdemo$$
$$edit$$
let promise = new Promise(function (resolve, reject) {
    resolve("三眼鸭")
})

promise
    .then(function (value) {
        console.log(value) // 三眼鸭
        return "三眼鸡"
    })
    .then(function (value) {
        console.log(value) // 三眼鸡
        return "三眼鹅"
    })
    .then(function (value) {
        console.log(value) // 三眼鹅
    })

如果返回的是一个 promise, 那么会等待其结果后。

$$jsdemo$$
$$edit$$
let promise = new Promise(function (resolve, reject) {
    resolve("三眼鸭")
})

promise
    .then(function (value) {
        console.log(value) // 三眼鸭
        return new Promise(function (resolve, reject) {
            setTimeout(() => resolve("三眼鸡"), 3000)
        })
    })
    .then(function (value) {
        console.log(value) // 三眼鸡
    })

如果抛出了一个错误,那么便会被接下来的 catch 捕获到。

$$jsdemo$$
$$edit$$
let promise = new Promise(function (resolve, reject) {
    resolve("三眼鸭")
})

promise
    .then(function (value) {
        throw "错误"
    })
    .catch(function (error) {
        console.log(error) // 错误
    })