promise應用及原生實現promise模型

2022-06-02 18:45:10 字數 4005 閱讀 3025

一、先看乙個應用場景

傳送乙個請求獲得使用者id, 然後根據所獲得的使用者id去執行另外處理。當然這裡我們完全可以使用**,即在請求成功之後執行callback;

但是如果又新增需求呢?比如獲得使用者id之後,再傳送請求去獲取使用者名稱,之後再獲取使用者其他資訊。。。。這就陷入了callback-hell,而且**很難維護。promise可以解決這樣的問題。

function getuserid() )

})}getuserid().then(function(id) )

上面的**是不是看起來不叫順手了。 

二、promise是什麼?

它簡單說就是乙個容器,就是乙個建構函式。裡面儲存著某個未來才會結束的事件(通常是乙個非同步操作)的結果。從語法上說,promise 是乙個物件,從它可以獲取非同步操作的訊息。promise 提供統一的 api,各種非同步操作都可以用同樣的方法進行處理。

也可以說promise 是非同步程式設計的一種解決方案,其實我們經常使用$.ajax()就是一種promise的解決方案

更加詳細的內容可以看阮一峰的《promise物件》。

三、can i use

現在更多的瀏覽器對promise提供了原生的支援。axios基於 promise 的 http 請求就是乙個常用的應用栗子。

三、寫點demo

當對概念有點燃的時候,回頭看看自己寫過的demo,肯定有不一樣的理解,這即是部落格的乙個好處之一

function getnumber()

else

}, 2000);

});

}getnumber()

.then(function(data))

.catch(function(data));

封裝乙個函式,引數是定時器的時間引數

function sleep (time) 

sleep(5000).then(function(val)秒之後起床`);

});

四、怎麼實現乙個promise?1、最簡單的promise雛形

function promise(fn);

//**函式陣列,肯能同時有多個**

this.callbacks = ;

//執行函式

const resolve = val =>);

},0)

}; //將resolve作為實參傳入fn中,fn的非同步什麼時候有結果再去執行resolve

fn(resolve);

}//註冊**函式,successcallback將會被壓進promise容器中的callbacks佇列

promise.prototype.then = function(successcallback);

//測試用例

const promise = new promise(function(resolve),2000)

})promise.then(function(val));

說明:(1)、建立promise例項時候傳進的函式函式被賦予乙個函式型別的引數resolve,resolve接收乙個引數,代表非同步但返回的結果;當非同步操作成功之後,就會執行resolve方法;

(2)、呼叫then方法,將想要在promise非同步操作成功時執行的**放入callbacks佇列,其實也就是註冊**函式,

(3)、第一步中執行resolve方法就就是執行callbacks陣列中的**函式,依次執行;

(4)、加入延遲機制,通過settimeout(),保證在resolve執行之前,then方法已經註冊完所有的**。

2、加入狀態

pending :即將發生的狀態

fulfilled : 成功狀態

rejected : 失敗狀態

function promise(fn);

//**函式陣列

this.callbacks = ;

//一開始的狀態是發生的狀態

this.status = 'pending';

//立即執行的引數,初始為null

this._val = object.create(null);

//執行函式

const resolve = val =>);

})}; //將resolve作為實參傳入fn中並執行,fn的非同步什麼時候有結果再去執行resolve函式

fn(resolve);

}promise.prototype.then = function(successcallback)

successcallback(this._val);

};const promise = new promise(function(resolve),2000)

})promise.then(function(val));

//此時promise例項執行的時候,status已經變為了『fulfill』,在此之後呼叫then新增的新**,都會立即執行。

settimeout(() => );

}, 3000)

3、鏈式

如果在then函式裡面再注入乙個promise呢?

主要是對then函式和resolve啊含糊的額改造,看這裡~

《30分鐘,讓你徹底明白promise原理》

4、es6實現寫法

class cutepromise 

this.state = 'pending';

this.chained = ;

const resolve = res =>

this.state = 'fulfilled';

this.internalvalue = res;

for (const of this.chained)

}; const reject = err =>

this.state = 'rejected';

this.internalvalue = err;

for (const of this.chained)

}; try catch (err) }

then(onfulfilled, onrejected) else if (this.$state === 'rejected') else );

} }}//test

let p = new cutepromise(resolve => );

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

p = new cutepromise((resolve, reject) => );

p.then(() => {}, err => console.log('async error:', err.stack));

p = new cutepromise(() => );

p.then(() => {}, err => console.log('sync error:', err.stack));

五、總結1、promise的建構函式接收乙個函式型別的引數,並且傳入兩個引數:resolve,reject,分別表示非同步操作執行成功後的**函式和非同步操作執行失敗後的**函式。

2、resolve()執行時傳入的引數,傳到了之後呼叫的.then()中。

3、reject()執行時傳入的引數,傳到之後呼叫的.catch()中。在裡面丟擲**函式的異常,不會卡死js.

4、呼叫getnumber()時候返回promise的例項物件,這樣就 支援了了鏈式的呼叫。

Promise 的 用法及實現

promise 物件用於乙個非同步操作的最終完成 或失敗 及其結果值的表示。語法new promise function resolve,reject 在函式體中,呼叫 resolve 會把狀態改為成功 reject 把狀態改為失敗,狀態只可操作一次.狀態改變之後,會繼續執行promise的then...

原生js實現Promise(簡版 公升級版)

js 實現 promise 之前查閱了幾篇blog作為參考,最終參考了 mdn語法的理解 var executor function resolve,reject new promise executor promise建構函式 接收的乙個executor函式 executor函式 接收兩個引數 r...

非同步解決方案promise及原始碼實現

js語言的特性,造就了特別的非同步處理方式,我記得以前用的最多的就是 函式,那個時候寫jquery的ajax時候,特別喜歡寫這種 ajax 後乙個ajax的傳送需要依賴前面的ajax的返回,也許有的朋友說還好啊,其實一兩個確實還好,但是多了就比較暈。不直觀。後面除錯起來有點麻煩。後來很多瀏覽器就自己...