Promise 與 Confirm 提示框

Promise 是 ES6 中很是重要的概念。相較於回調函數和事件監聽,Promise 能夠更好的解決了異步編程中遇到的問題。vue

Promise 是 ES6 新引入的對象。使用 Promise 封裝一個異步過程,避免了使用回調函數,鏈式調用讓代碼更加清晰。git

1. Promsie 的基本概念

Promise 對象是個構造函數,經過 new 建立一個 Promise 實例。github

const promise = new Promise((resolve, reject) => {})複製代碼

一個 Promise 對象有 3 種狀態:ajax

  • pending: 初始狀態,不是成功或失敗狀態。
  • fulfilled: 意味着操做成功完成。
  • rejected: 意味着操做失敗。

執行 Promise 回調中的 resolve 與 reject 函數改變 Promise 對象的狀態。編程

2. Promsie 的應用

使用 Promise 實現一個簡單的 ajax 函數是個很是好的例子。promise

// 封裝 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 回調中能夠獲取到這些參數。這樣的話,即可以對異步過程傳遞出的信息作出相對應的處理。app

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 是一個很是好的工具。但願你們能掌握它的用法。

參考資料

相關文章
相關標籤/搜索