Promise,ES6中定義的規範,不會使用Promise,都不敢說本身用過ES6,大部分介紹Promise的規範的文章對於新手小白來講看得雲裏霧裏,且並非通俗易懂。本文經過實例介紹講述Promise中then的的最通俗應用理解,代碼創建在不出現異常的狀況的操做下,不嚴謹之處,請以官方規範爲標準。web
先看一下下面4個Promise到底有什麼區別呢?promise
func().then(function () { return cb(); }); func().then(function () { cb(); }); func().then(cb()); func().then(cb);
若是你知道答案,如下內容你能夠不用繼續。函數
上面的代碼過於簡單,運行時話須要稍微進行一點擴展,每一個方法中都打印出promise上一步的調用值,爲了方便我給每一個方法加了一個下標輸出,分別是一、二、三、4。spa
let func = function() { return new Promise((resolve, reject) => { resolve('返回值'); }); }; let cb = function() { return '新的值'; } func().then(function () { return cb(); }).then(resp => { console.warn(resp); console.warn('1 =========<'); }); func().then(function () { cb(); }).then(resp => { console.warn(resp); console.warn('2 =========<'); }); func().then(cb()).then(resp => { console.warn(resp); console.warn('3 =========<'); }); func().then(cb).then(resp => { console.warn(resp); console.warn('4 =========<'); });
不賣關子,直接看結果code
首先要明白Promise中then方法會幹什麼事情!blog
官方文檔是這樣定義的:ip
一個 promise 必須提供一個 then 方法以訪問其當前值、終值和據因。promise 的 then 方法接受兩個參數:文檔
promise.then(onFulfilled, onRejected) Todo:這裏只介紹onFulfilled,因此刪除了關於onRejected的規範定義get
onFulfilled 和 onRejected 都是可選參數。回調函數
若是 onFulfilled 不是函數,其必須被忽略
若是 onFulfilled 是函數:當 promise 執行結束後其必須被調用,其第一個參數爲 promise 的終值
在 promise 執行結束前其不可被調用
其調用次數不可超過一次
用通(ren)俗(hua)的話來講:
then方法提供一個供自定義的回調函數,若傳入非函數,則會忽略當前then方法。
回調函數中會把上一個then中返回的值當作參數值供當前then方法調用。
then方法執行完畢後須要返回一個新的值給下一個then調用(沒有返回值默認使用undefined)。
每一個then只可能使用前一個then的返回值。
直觀的圖:
有了上面的定義咱們帶着三個疑問來回答問題:
執行第一個方法:
func().then(function () { return cb(); }).then(resp => { console.warn(resp); console.warn('1 =========<'); });
function () { return cb(); }
顯而易見,是傳入了回調函數的
回調函數中把cb執行後的返回值當作then中的返回值,因此輸出了「新的值」;
執行第二個方法:
func().then(function () { cb(); }).then(resp => { console.warn(resp); console.warn('2 =========<'); });
function () { cb(); }
then回調方法,只是執行了cb方法,並無return值,定義中講過若then沒有返回值,提供給下一個then使用的參數就是undefined,因此打印出來的是undefined;
執行第三個方法:
func().then(cb()).then(resp => { console.warn(resp); console.warn('3 =========<'); });
func().then(cb())
then中cb()執行後返回的並非一個函數,在Promise規範中會自動忽略調當前then,因此會把func中的返回值供下一個then使用,輸出了「返回值」
執行第四個方法:
func().then(cb).then(resp => { console.warn(resp); console.warn('4 =========<'); });
func().then(cb)
第一個方法在回調內部返回cb執行後的值,第四個方法則直接把cb當作回調,第一個方法與第四個方法殊途同歸之妙,因此也輸出了「新的值」。
題目出處:http://web.jobbole.com/82601/
Promise規範:https://promisesaplus.com/