# 什麼是Promise (含如何判斷一個值是Promise) > 本文旨在對 Promise 的規範進行解釋, 便於讀者在學習 Promise 的過程中梳理 Promise 之間的操作關係, 不對具體的代碼實現和Promise用法進行解釋. > > 比如, 為什麼 [[MDN-await]](ht ...
什麼是Promise (含如何判斷一個值是Promise)
本文旨在對 Promise 的規範進行解釋, 便於讀者在學習 Promise 的過程中梳理 Promise 之間的操作關係, 不對具體的代碼實現和Promise用法進行解釋.
比如, 為什麼 [MDN-await] 中要提及一個 thenable 對象, 而且這個 thenable 對象還可以和 Promise 實例一樣使用
await
等待處理, 這就涉及到了下麵的內容.
由於筆者編程水平的限制, 不可避免存在錯漏或者語意不清的地方.
Promise A+ 規範
參考資料: [Promises/A+]
在 ES6 之前,社區已經有了 Promise A+ 規範, 該規範定義了 Promise 的行為和介面. 根據規範, 任何具有 .then()
方法的函數或對象都可以被認為是一個 Promise ,並且可以進行 Promise 之間的操作。
這個具有 .then()
方法的函數/對象被稱為 thenable 對象, 你可以在 [MDN-Promise#thenable] 和 [Promises/A+] 查閱到相關資料.
如果讀者您熟悉 ES6 中的 Promise , 那麼對 Promise A+ 規範一定不陌生, 因為 ES6 中的 Promise 就是基於 Promise A+ 規範的官方實現和拓展. 我們可以將 ES6 的 Promise 稱為 Promise 對象, 在 ES6 之前, 第三方庫實現的 Promise A+ 規範對象稱為 thenable 對象.
該規範旨在於解決回調地獄和非同步實現不統一的問題. 早在 ES6 之前, 就有很多第三方庫遵守和支持這個規範. 比如 jQuery 中的 $.ajax() / $.get()
等方法返回的就是一個 JQuery 實現的 thenable 對象.
ES6 Promise
基於 Promise A+ 規範, 在 ES6 中新增了一個構造函數 Promise
, 通過實例化 Promise (new Promise()
) 可以新建一個 Promise 對象, 這個對象是一個符合 Promise A+ 規範的對象 .
如果為了便於理解, 我們可以將 Promise 對象 簡單理解為一個繼承了 thenable 對象 的對象.
不過在 Promise A+ 的基礎上, ES6還拓展了更多的功能, 比如 .catch()
方法, .finally()
方法 , 靜態方法 Promise.all()
等等, 具體可以查閱 MDN-Promise .
需要另外瞭解的一點是, .catch( (error) => {} )
方法本質上就是第一個參數傳入了空參數的.then( undefined, (error) => {} )
方法.
最小實現的 Promise 和最大實現的 Promise
綜上所述, 我們可以將 Promise A+ 規範規定的 Promise 稱為最小實現的 Promise, 也就是 thenable
對象; 將 ES6 的 Promise 成為最大實現的 Promise, 即 Promise
對象.
如果要檢測一個值是否為最小實現的 Promise , 只需要檢測是否函數/對象, 並且存在 .then()
方法即可.
如果要檢測一個值是否為最大實現的 Promise, 則只需要在上面的檢測的基礎上, 添加一個 .finally()
方法的檢測.
什麼是Promise
在 Promise A+ 規範中, Promise 就是一個具有 .then()
方法的函數或者對象.
在 ES6(ES2015) 中, Promise 是一個構造函數, 通過這個構造函數可以實例化一個符合 Promise A+ 規範的對象.
在 ES7(ES2016) 及其之後的版本, 還可以使用 await / async 去調用所有符合 Promise A+ 規範的對象, 包括一些第三方庫自己實現的符合 Promise A+ 規範的對象.
只要是符合 Promise A+ 規範的 Promise , 那麼它們之間就可以互相操作.
工具函數, 檢測一個對象是否為Promise
通常不會直接使用類似
value instanceof Promise
的判斷, 而是給予 Promise A+ / ES6 Promise 規範判斷.
最小限定的檢測, 檢測是否為 thenable
對象.
/**
* 判斷傳入參數是否為 Promise (最小實現)
* @param { any } value
* @return { boolean } 是否為 Promise
* @description 代碼源於第三方庫 is-promise
* @tutorial https://www.npmjs.com/package/is-promise
* */
function isPromise( value ) {
return !!value
&& (typeof value === 'object' || typeof value === 'function')
&& typeof value.then === 'function';
}
取消了 typeof value === 'function'
的判斷, 因為通過 new Promise()
實例化的值一定是一個對象.
如果想更嚴格一下, 還可以將 .catch()
方法也加進判斷, 也有些工具函數只判斷 .then()
方法和 .catch()
方法是否存在, 這隻看使用者是想如何限定 Promise 的範圍.
/**
* 判斷傳入參數是否為 Promise (最大實現)
* @param { any } value
* @return { boolean } 是否為 Promise
* */
function isStrictPromise( value ) {
return !!value
&& typeof value === 'object'
&& typeof value.then === 'function'
&& typeof value.finally === 'function';
}