1. 程式人生 > >3行程式碼實現一個簡易版promise

3行程式碼實現一個簡易版promise

前言

作為一個後端過來的同學,剛入門前端的時候,被js種種「反人類」的概念折騰的死去活來的.
其中一個印象比較深刻的,就是promise,感覺實在太難理解了…所有就有了寫個簡單的promise的想法.
希望能幫助到一些跟我一樣,感覺promise很難理解的新同學.

promise的教程網上多如牛毛,其中寫的比較通俗易懂的莫過於阮一峰的es6,反正我是他的書才懂的.
所以今天,我們也不會來複述一遍如何使用promise,今天我們從另一個角度學習promise,
先自己動手造一個輪子–實現一個最簡單的promise,解決 回撥地獄 的問題.

簡單實現

請看程式碼

function
easyPromise (fn) {
this.then = cb => this.cb = cb this.resolve = data => this.cb(data) fn(this.resolve) }

詳解

上面的程式碼就實現了一個簡單的,實現then回撥的「promise」,這裡為了縮短程式碼量,用了es6的簡寫,實際展開應該是這樣

function easyPromise (fn) {
    var that = this

    // 第一步,定義 then()
    this.then = function (cb) {
        //先將 then() 括號裡面的引數(回撥函式)儲存起來
that.cb = cb } // 定義一個 resolve this.resolve = function(data) { that.cb(data) } // 將 resolve 作為回撥函式,傳給fn fn(this.resolve) }

接下來我們看看如何使用

new easyPromise((resolve) => {
    setTimeout(() => {
        resolve("延時執行")
    }, 1000)
}).then((data) => {
    console.log(data)
})

結果: 控制檯在1秒之後,輸出 延時執行

同樣為了方便理解,我們不妨把以上程式碼寫好理解一點.

// 定義一個要傳給 promise 的函式,它接收一個函式(resolve)作為引數。
// resolve 的作用是在合適的時間,通知 promise 應該要執行 then 裡面的回撥函數了。
function promiseCallback (resolve) {
   setTimeout(() => {
      resolve("延時執行")
   }, 1000)
}

// 定義一個 要傳給 then 的回撥函式
function thenCallback (data) {
    console.log(data)
}

// 例項化 promis,並分別傳入對應的回撥
new easyPromise(promiseCallback)
.then(thenCallback)

tips: promise.then() 的時候,並沒有馬上執行括號裡面的回撥函式,只是把括號裡面的回撥函式儲存起來.

我們來梳理一下執行流程

  1. 先通過 thenthenCallback 存起來

    this.then = function (cb) {
      that.cb = cb
    }

    這裡的 cb , 就是上例的 thenCallback 所以其實可以等價於 this.cb = thenCallback

  2. 執行 promise 括號裡的函式,並把事先定義好的 resolve 函式作為引數傳給他

    fn(this.resolve)

    這裡的 fn , 就是上例的 promiseCallback

  3. 執行 promiseCallback 我們的邏輯就跳到 promiseCallback 函式內部去

    setTimeout(() => {
      resolve("延時執行")
    }, 1000)

    邏輯很簡單,就是等待1秒後,執行 resolve 函式, 這個 resolve 哪來的呢?

    fn(this.resolve) -> promiseCallback (resolve) -> resolve

  4. 執行 resolve 我們的邏輯就跳到 resolve 函式內部去

    that.cb(data)

    這個 that.cb 又是哪來的呢? 就是我們第一步儲存的 then括號裡面的回撥函式,也就是 thenCallback

    console.log(data)

    所以就在1秒後輸出 延時執行

最後

如果覺得本文對您有用,請給本文的github加個star,萬分感謝

另外,github上還有其他一些關於前端的教程和元件,
有興趣的童鞋可以看看,你們的支援就是我最大的動力。