function Promise(fn) {
var state = 'pending',
//這個(gè)value記錄的是promise本身值 即用于它.then(onFulfilled)的參數(shù)值
value = null,
//記錄它對(duì)應(yīng)的異步回調(diào)對(duì)象,當(dāng)resolve執(zhí)行的時(shí)候,會(huì)異步執(zhí)行這些函數(shù)
deferreds = [];
//then會(huì)將一下符合條件的回調(diào)加入 deferred
//須知
/* new Promise_A_(resolve => resolve()).then(onFulfilled_B_)_C_
最麻煩的是 onFulfilled 返回也返回一個(gè) promise對(duì)象 下面討論這種情況
* 假設(shè)第一個(gè) new Promise 為 Promise A
* onFulfilled 返回的promise 為 Promise B
* then 本身返回的Promise 為 Promise C
* 必須是 A 狀態(tài)確定即執(zhí)行resolve 然后在 B 狀態(tài)確定 然后再是 C狀態(tài)確定
* 那么如何才能確保上面的流程執(zhí)行?
* 由于執(zhí)行resolve狀態(tài)才能確定, 那么上面執(zhí)行情況一定是
* A 中的 resolve 中 調(diào)用 B 的 resolve B的resolve中 調(diào)用C的resolve
* 參數(shù)如何傳遞? 利用好promise 里面的value就行,而且每個(gè)then里面的onfulfilled函數(shù)的返回值都作
*/
this.then = function (onFulfilled, onRejected) {
//每個(gè)then自動(dòng)返回一個(gè)promise,
return new Promise(function (resolve, reject) {
//這里可以獲取 這個(gè)then創(chuàng)建的promise的resolve函數(shù) 因?yàn)樗锩鏁?huì)調(diào)用fn(resolve)
//獲取這個(gè)resolve函數(shù)可以做流程控制 控制這個(gè)resolve什么時(shí)候執(zhí)行 也就是promise C
//什么時(shí)候狀態(tài)確定
//promiseC 什么時(shí)候狀態(tài)確定呢?它必須在 onFulfilled 返回的promiseB狀態(tài)確定后才能確定
//由于PromiseB 在PromiseA的 resolve函數(shù)里面執(zhí)行 所以我們暫時(shí)把 onFulfilled 和 這個(gè)resolve
//保存起來(lái)
//promise中的fn是 立即執(zhí)行的 不用擔(dān)心handle獲取不到數(shù)據(jù)
handle({
onFulfilled: onFulfilled || null,
onRejected: onRejected || null,
resolve: resolve,
reject: reject
});
});
};
//這個(gè)handler是非常重要的,異步里面當(dāng)前promise狀態(tài)確定了以后也直接調(diào)用它
//之前說(shuō)了 promsieA 狀態(tài)確定 才執(zhí)行promiseB的then C也同理
function handle(deferred) {
//當(dāng)當(dāng)前的promise對(duì)象為pendding時(shí)候 直接加入到異步回調(diào)中
if (state === 'pending') {
deferreds.push(deferred);
return;
}
//當(dāng)前promise狀態(tài)已經(jīng)確定了話 就直接執(zhí)行then參數(shù)函數(shù),當(dāng)然如果存在話
var cb = state === 'fulfilled' ? deferred.onFulfilled : deferred.onRejected,
ret;
//這里是非常巧妙的 如果then參數(shù)不處理的話,自動(dòng)交給then返回的promise對(duì)象處理
//起到冒泡的作用
if (cb === null) {
cb = state === 'fulfilled' ? deferred.resolve : deferred.reject;
//如果then參數(shù)不出來(lái) 那么之前把promiseA的value復(fù)制給promiseC的resolve
cb(value);
return;
}
//如果then的參數(shù)處理了 比如onFulfilled
//那么把onFuillfilled的返回值 當(dāng)成value傳遞給promiseC
//這個(gè)返回值 分為兩種情況 一種為 promsie 一種為 普通值
//如果為promise的話 那么必須等待這個(gè)promiseB狀態(tài)確定后 promiseC才執(zhí)行它的resolve
ret = cb(value);
deferred.resolve(ret);
}
function resolve(newValue) {
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
var then = newValue.then;
//如果 onFulfilled 返回值為promise對(duì)象時(shí)
if (typeof then === 'function') {
//那么 先執(zhí)行promiseB的then 然后把它的value 傳遞給promiseC的resolve 或者reject
//即實(shí)現(xiàn)了 promsieB-->到promiseC的控制
then.call(newValue, resolve, reject);
return;
}
}
//如果不是promise對(duì)象的話, 直接調(diào)用異步回調(diào) 而且設(shè)置promise對(duì)象的value
state = 'fulfilled';
value = newValue;
finale();
}
function reject(reason) {
state = 'rejected';
value = reason;
finale();
}
function finale() {
// resolve后執(zhí)行的回調(diào) 必須異步的
setTimeout(function () {
deferreds.forEach(function (deferred) {
handle(deferred);
});
}, 0);
}
fn(resolve, reject);
}
promise
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
- 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
- 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
- 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
- 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
- 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 是什么 Promise是一種對(duì)異步操作的封裝,主流的規(guī)范是Promise/A+。Promise可以使得異步代碼層次...
- (1)ES6方式 http://liubin.github.io/promises-book/#promise-i...
- 問(wèn)題一 在系列(一)的開(kāi)頭,我曾經(jīng)舉過(guò)一個(gè)例子,但其中包含著錯(cuò)誤(現(xiàn)已更正),現(xiàn)簡(jiǎn)化如下: 原因:之所以會(huì)出現(xiàn)這種...
- 大三下學(xué)期了 各種實(shí)習(xí)開(kāi)始轟炸了 二月初學(xué)校國(guó)際處實(shí)習(xí)沒(méi)去 現(xiàn)在惠靈頓國(guó)際學(xué)校實(shí)習(xí)也不打算去 不過(guò)倒想去面試看看常...