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()
的時候,並沒有馬上執行括號裡面的回撥函式,只是把括號裡面的回撥函式儲存起來.
我們來梳理一下執行流程
先通過
then
把thenCallback
存起來this.then = function (cb) { that.cb = cb }
這裡的
cb
, 就是上例的thenCallback
所以其實可以等價於this.cb = thenCallback
執行
promise
括號裡的函式,並把事先定義好的resolve
函式作為引數傳給他fn(this.resolve)
這裡的
fn
, 就是上例的promiseCallback
執行
promiseCallback
我們的邏輯就跳到promiseCallback
函式內部去setTimeout(() => { resolve("延時執行") }, 1000)
邏輯很簡單,就是等待1秒後,執行
resolve
函式, 這個resolve
哪來的呢?fn(this.resolve)
->promiseCallback (resolve)
->resolve
執行
resolve
我們的邏輯就跳到resolve
函式內部去that.cb(data)
這個
that.cb
又是哪來的呢? 就是我們第一步儲存的 then括號裡面的回撥函式,也就是thenCallback
console.log(data)
所以就在1秒後輸出
延時執行
最後
如果覺得本文對您有用,請給本文的github加個star,萬分感謝
另外,github上還有其他一些關於前端的教程和元件,
有興趣的童鞋可以看看,你們的支援就是我最大的動力。