實現Promise的first等各種變體

2022-01-19 08:45:51 字數 3781 閱讀 7591

本篇文章主要是想通過es6中promise提供的幾個方法,來實現諸如first、last、none、any等各種變體方法!

在標準的es6規範中,提供了promise.allpromise.race兩種,我們首先來了解下這兩個方法是幹嘛的,方便我們後面工作的展開。promise.all中所有的promise例項都處於完成狀態,該方法才進入完成狀態,否則任意乙個被拒絕,則該方法進入拒絕狀態,並捨棄其他所有完成的結果,拒絕原因是第乙個被拒絕的例項的原因。promise.race中任意的乙個promise例項變成完成狀態或者拒絕狀態,則race結束,race的結果即為第乙個變成最終狀態的結果!更詳細的可以參考下阮一峰的文章promise物件之promise.all。

在開始編寫各種變體方法之前,這裡我們首先定義幾個一會兒要使用的幾個promise例項:

/**

* 建立乙個promise物件的例項

* @param name 該例項的名稱

* @param flag 返回的結果狀態:完成還是拒絕

* @param diff 延遲的時間

*/var createpromisecase = ( name, flag, diff ) => , diff );

} );

};var p1_suc_100 = createpromisecase( 'p1-suc-100', true, 100 );

var p2_suc_500 = createpromisecase( 'p2-suc-500', true, 500 );

var p3_suc_300 = createpromisecase( 'p3-suc-300', true, 300 );

var p4_fail_400 = createpromisecase( 'p4-fail-400', false, 400 );

var p5_fail_200 = createpromisecase( 'p5-fail-200', false, 200 );

2.1 promise.first

場景:乙個頁面當前正處於loading狀態,同時請求了多個介面,無論哪個介面正確返回結果,則loading效果取消!或者其他的要獲取獲取第乙個完成狀態的值。

這裡就要用到了promise.first了,只要任意乙個promise例項變成完成狀態,則promise.first變成完成狀態。其實這裡並不適合promise.race方法,因為第乙個變成拒絕狀態的例項也會啟用promise.race,

if ( !promise.first ) 

} );

} );

} );

};}

呼叫方式:

promise.first([p4_fail_400, p2_suc_500, p3_suc_300])

.then(res => console.log(res)) // p3-suc-300

.catch(e => console.error(e))

可以看到每次獲取的p3_suc_300的值,因為p4是失敗的狀態,p2的完成狀態沒有p3快,因此這裡獲取到了p3的結果。

2.2 promise.last

與promise.first對應的則是promise.last,獲取最後變成完成狀態的值。這裡與promise.first不同的是,只有最後乙個promise都變成最終態(完成或拒絕),才能知道哪個是最後乙個完成的,這裡我採用了計數的方式,thencatch只能二選一,等計數器達到list.length時,執行外部的resolve。

if ( !promise.last ) 

}promiselist.foreach( pms => )

.catch(fn);

} )} )

}}

呼叫方式:

promise.last([p1_suc_100, p2_suc_500, p5_fail_200, p3_suc_300, p4_fail_400])

.then(res => console.log(res)) // p2-suc-500

.catch(e => console.error(e))

p2需要500ms才能完成,是最晚完成的。

2.3 promise.none

promise.none與promise.all正好相反,所有的promise都被拒絕了,則promise.none變成完成狀態。該方法可以用promise.first來切換,當執行promise.first的catch時,則執行promise.none中的resolve。不過這裡我們使用promise.all來實現。

if ( !promise.none )  )

} ) )

}}

呼叫方式:

promise.none([p5_fail_200, p4_fail_400])

.then(res => console.log(res))

.catch(e => console.error(e))

// then的輸出結果:

// [

// error: testpromise is error, name: p5-fail-200,

// error: testpromise is error, name: p4-fail-400

// ]

兩個promise都失敗後,則promise.none進入完成狀態。

2.4 promise.any

promise.any表示只獲取所有的promise中進入完成狀態的結果,被拒絕的則忽略掉。

if ( !promise.any )  );

} ) ).then( ( res ) => )

} )}

}

呼叫方式:

promise.any([p1_suc_100, p2_suc_500, p5_fail_200, p3_suc_300, p4_fail_400])

.then(res => console.log(res)) // ["p1-suc-100", "p3-suc-300", "p2-suc-500"]

.catch(e => console.error(e))

2.5 promise.every

最後乙個的實現比較簡單,所有的promise都進入完成狀態,則返回true,否則返回false。

if (!promise.every) 

}

呼叫方式:

promise.every([p1_suc_100, p2_suc_500, p3_suc_300])

.then(result => console.log('promise.every', result)); // promise.every true

promise.every([p1_suc_100, p4_fail_400])

.then(result => console.log('promise.every', result)); // promise.every false

promise還有各種方面的應用,很多類庫也都實現了類似的方法,這裡也僅僅是鄙人拙見,稍微實現了promise的變體方法,加深下對promise的理解。

promise的粗糙實現

function promise fn else this.task.pointer then佇列指標自增 doer then佇列指標自增 this.task.push f if this.pending init return this 把當前物件返還回去 this.catch fn this.e...

Promise的簡單實現

promise 是非同步程式設計的一種解決方案 從語法上講,promise是乙個物件,從它可以獲取非同步操作的訊息 從本意上講,它是承諾,承諾它過一段時間會給你乙個結果。promise有三種狀態 pending 等待態 fulfiled 成功態 rejected 失敗態 狀態一旦改變,就不會再變。創...

自己實現Promise

class mypromise 0 resolve obj reject obj then func,errfunc function fff resolve,reject test var m new mypromise fff var num 1 m.then obj obj console.l...