一比一還原axios原始碼(七) 取消功能

2022-10-09 00:51:11 字數 3725 閱讀 6043

按照慣例,我們先來看下官方的例子:

你可以通過axios的canceltoken工廠函式,生成乙個source,然後把這個物件作為引數傳遞給axios,最後,需要取消的時候呼叫source的cancel方法即可。

你還可以通過在引數中繫結new canceltoken的引數中的**,來賦值執行取消操作。

最後,你還可以通過fetch的api來執行取消操作。ok,我們來看下如何實現這樣的取消功能。首先,我們先在lib目錄下建立乙個cancel資料夾,然後在cancel下建立個cancel.js:

//

這這個是啥呢?就是你取消請求的時候丟擲去的錯誤型別的類

//很簡單,就是個message

function

cancel(message)

//把它轉換成字串的tostring方法的自定義實現

cancel.prototype.tostring = function

tostring() ;

//原型上繫結個__cancel__,給iscancel做判斷的條件。

cancel.prototype.__cancel__ = true

;export

default cancel;

**很簡單,實際上就是乙個取消的訊息字串。並改寫了原型上的tostring方法。然後我們iscancel.js:

export default

function

iscancel(value)

它是用來判斷當前的請求是否已經被取消了,以便我們去做判斷條件後的其他操作。關鍵的來了,我們來建立乙個canceltoken.js:

function

canceltoken(executor)

//儲存promise resolve方法的便利

varresolvepromise;

//給例項繫結個promise,並把resolve賦值給resolvepromise

this.promise = new promise(function

promiseexecutor(resolve) );

var token = this;

//eslint-disable-next-line func-names

this.promise.then(function

(cancel)

token._listeners = null

; });

//eslint-disable-next-line func-names

this.promise.then = function

(onfulfilled) ).then(onfulfilled);

promise.cancel = function

reject() ;

return

promise;

};executor(

function

cancel(message)

token.reason = new

cancel(message);

resolvepromise(token.reason);

});}

我們來看下他做了啥。首先,判斷下傳入的引數是不是乙個函式,如果不是函式就丟擲乙個錯誤。然後儲存乙個promise的resolve方法,下面呢,把canceltoken的例項也就是this,賦值給token變數,然後:

this.promise.then(function

(cancel)

token._listeners = null

; });

這段**,迴圈執行token上訂閱的事件,執行後置為null。要注意,這裡的then方法的**函式,這裡我理解的,之前resolvepromise還沒執行呢,所以執行resolvepromise的時候,就是執行上面的then的**的時候。

var

oncanceled;

function

done()

if(config.signal)

}

首先,oncanceled就是如果存在取消的canceltoken引數的話,那麼就會生成乙個oncanceled函式,done方法就是移除的函式。很好理解吧。然後咱們往下:

if (config.canceltoken ||config.signal) 

reject(

!cancel || (cancel && cancel.type) ? new cancel("canceled") : cancel

);request.abort();

request = null

; };

config.canceltoken &&config.canceltoken.subscribe(oncanceled);

if(config.signal)

}

這一塊,就是如果存在著兩個引數,那麼給oncanceled賦值乙個函式,之前說過了,signal是啥呢,其實是類似fetch的使用方法的乙個引數,最開始的例子裡說過了。看一下哈,其實這塊的**很好理解,就是繫結或執行原生的取消方法嘛。

我們來回顧下,如果存在取消函式的話,還呼叫了canceltoken上的subscribe方法訂閱了一下oncanceled函式,subscribe很簡單,就是乙個新增操作:

canceltoken.prototype.subscribe = function

subscribe(listener)

if (this

._listeners)

else

};

有subscribe自然也有unsubscribe:

canceltoken.prototype.unsubscribe = function

unsubscribe(listener)

var index = this

._listeners.indexof(listener);

if (index !== -1)

};

就是個移除操作。然後source靜態方法是這樣的:

canceltoken.source = function

source() );

return

;};

就是把canceltoken的例項和取消函式返回了。所以,我們在使用的時候,可以像這樣來使用:

const canceltoken =axios.canceltoken;

const source =canceltoken.source();

axios

.get("/c7/get", )

.catch(function

(e)

});source.cancel("operation canceled by the user.");

好了,到這裡canceltoken的實現就完成了,詳細的**大家可以去專案裡檢視。最後一篇就新增一些小的功能點,十分簡單。

幾種搜尋演算法原理比一比

a搜尋 總代價 f n g n h n 其中g n 為從初始狀態到達該狀態的代價 這裡乙個狀態也就是a演算法裡常說的乙個節點 h n 為從當前狀態到目標狀態的預估代價。因此,該演算法的思路就是,每次尋找總代價f n 最小的點進行擴充套件,直到找到終點。a 的具體過程可參考這篇部落格,可參考這篇部落格...

Nacos原始碼一 原始碼啟動

一 nacos 原始碼本地啟動 官方單機啟動文件 將原始碼匯入到idea,然後開啟console專案中的配置檔案 按照nacos文件中單機啟動模式修改mysql配置 資料庫連線串需要有時區 useunicode true characterencoding utf8 servertimezone u...

Vue原始碼 一

很多人想看原始碼,但是不知道從哪一塊下手,所以這裡我說一下我是怎麼找入口的。首先dist資料夾中有vue.js,這是已經被打包好的js檔案,src中的所有js 都合併到了這裡,我們直接去看這個vue.js肯定是會懵逼的,1w多行跳來跳去的,所以我們是不是要找到打包的入口?那麼讓我們進入到script...