阅读 1123

Promise 与 Confirm 提示框

Promise 是 ES6 中非常重要的概念。相较于回调函数和事件监听,Promise 可以更好的解决了异步编程中遇到的问题。

Promise 是 ES6 新引入的对象。使用 Promise 封装一个异步过程,避免了使用回调函数,链式调用让代码更加清晰。

1. Promsie 的基本概念

Promise 对象是个构造函数,通过 new 创建一个 Promise 实例。

const promise = new Promise((resolve, reject) => {})复制代码

一个 Promise 对象有 3 种状态:

  • pending: 初始状态,不是成功或失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

执行 Promise 回调中的 resolve 与 reject 函数改变 Promise 对象的状态。

2. Promsie 的应用

使用 Promise 实现一个简单的 ajax 函数是个非常好的例子。

// 封装 XMLHttpRequest
funtion ajax () {
    return new Promise((resolve, reject) => {
        var req = new XMLHttpRequest()
        req.onreadystatechange = function () {
            if (this.readyState === XMLHttpRequest.DONE) {
                if (this.status === 200) {
                    resolve(this.responseText)
                } else {
                    reject(new Error('ajax error'))
                }
            }
        }
        req.open('GET', '/url')
        req.send()
    })
}
// 调用
ajax().then(res => {
    // ajax 成功之后的 responseText
}).catch(err => {})复制代码

resolve 与 reject 函数调用时的可以传递参数,在 Promise 实例之后的 then 与 catch 回调中可以获取到这些参数。这样的话,便可以对异步过程传递出的信息做出相对应的处理。

3. Confirm 提示框与 Promsie

一个常见的 confirm 提示框
一个常见的 confirm 提示框

上图是一个十分简单的 Confirm 提示框。其实,我们可以发现 Confirm 提示框也具有 3 种状态,跟 Promise 三种状态非常相像。提示框在创建时对应 pending ,点击取消之后对应 rejected ,点击确定之后对应 fulfilled。所以我们可以编写一个名 为 confirm 的函数 ,这个函数实现两个功能:

  1. 在创建 Confirm 组件之后,返回一个 Promise。
  2. 当用户点击确定或者取消按钮时改变这个 Promise 实例的状态。

那么就可以在调用 confirm 函数之后的 then 与 catch 中针对不同的操作做出相应的处理。
下面的伪码描述了这个过程。

confirm().then(() => {
    // 点击了 确定
}).catch(() => {
    // 点击了 取消
})复制代码

按照这个思路,我们来一步步实现这个 confirm 函数。

3.1 Confirm 组件

Confirm 组件类似于一个弹出层,其中的内容区域需要居中显示。使用 fixed 绝对定位 与 flex 布局可以实现。完整的代码点击这里

3.2 confirm 函数

实现的 confirm 的一些要点:

  1. 调用 confirm 函数,创建 Confrim 组件并同时返回一个 Promise 对象。
  2. 在按钮点击之后,改变 Promise 对象的状态,触发之后 then 或者 catch 执行,同时关闭弹出层,销毁组件。
import Vue from 'vue'
let currentMsg = null
let instance = null

const ConfirmConstructor = Vue.extend(require('./Index.vue'))
function confirm (option = {}) {
    instance = new ConfirmConstructor({
        el: document.createElement('div')
    })
    // ...
    // 弹出层再次隐藏时时销毁组件
    instance.$watch('display', function (val) {
    if (!val) {
        instance.$destroy(true)
        instance.$el.parentNode.removeChild(instance.$el)
    }
    instance.callBack = defaultCallBack
    document.body.appendChild(instance.$el)
    // 显示
    instance.display = true
    return new Promise((resolve, reject) => {
        currentMsg = { resolve, reject }
    })
  })
}

function defaultCallBack (action) {
    // ...
    if (action === 'confirm') {
        currentMsg.resolve('confirm')
    } else {
        currentMsg.reject('cancel')
    }
}

export default confirm复制代码

在需要的时候,导入 confirm 函数,通过链式调用即可。
完成的代码片段点击这里

4. 总结

本文简单介绍了一下 Promise 的概念,并且应用 Promise 实现了一个简单的 confirm 函数。从以上例子可以看出,对于一些异步操作, Promise 是一个非常好的工具。希望大家能掌握它的用法。

参考资料

关注下面的标签,发现更多相似文章
评论