如何获取.then的返回值_仅仅知道如何终止XHR请求,或许对你来说是不够的!
TLDR:
當(dāng)我們需要的時(shí)候,我們可以通過AbortController接口來終止一個(gè)或者多個(gè)請(qǐng)求。
前言
到目前為止,我們有兩個(gè)常用的基本的手段去發(fā)送請(qǐng)求進(jìn)而局部刷新頁(yè)面內(nèi)容,其一是XMR(XMLHttpRequest),其二是fetch,我們一個(gè)個(gè)說
XHR
對(duì)于XHR,我們或許已經(jīng)很熟悉了,當(dāng)我們想要發(fā)送一個(gè)請(qǐng)求的時(shí)候,我們可以這樣做:
const xhr = new XMLHttpRequest(); const method = 'GET'; const url = 'https://xxx';xhr.open(method, url, true); xhr.onreadystatechange = () => {if (xhr.readyState === 4) {// do something} } xhr.send();當(dāng)我們由于某種原因(比如重復(fù)請(qǐng)求)想要終止它的時(shí)候,我們只需要調(diào)用abort即可。
xhr.abort();很方便也很簡(jiǎn)潔,但是對(duì)于fetch呢?
fetch
首先我們看下fetch的基本定義:
- 接受一個(gè)必須的參數(shù)和一個(gè)可選的參數(shù)
- 定義要獲取的資源,地址或者Request對(duì)象
- 可選的配置對(duì)象,比如請(qǐng)求方式、body、credentials等等,其中我們需要知道的是signal,他的定義如下: 一個(gè)AbortSignal對(duì)象實(shí)例,允許你通過AbortController與fetch請(qǐng)求通信或者終止fetch
- 返回值是一個(gè)promise
看到這里我們已經(jīng)知道了答案,但是我們需要再去了解一下上文所說的AbortController.
AbortController
最初es6引入fetch的時(shí)候,其實(shí)就是沒有abort這樣的功能,不過廣大程序朋友們還會(huì)希望能有這個(gè)靈活的api,所以在2015年就有人提了這個(gè)issue,再次之后大家嘗試了注入promise式的取消或者是其他hack等等,經(jīng)過這份折騰最終我們迎來了AbortController和AbortSignal。
AbortController目前很簡(jiǎn)單,有一個(gè)制度的屬性AbortController.signal和一個(gè)用來中斷請(qǐng)求的.abort()
光說也沒啥意思,咱看代碼說話:
// 啟動(dòng)一個(gè)node服務(wù),其中包括一個(gè)api和一個(gè)html頁(yè)面const Koa = require('koa'); const fs = require('fs'); const app = new Koa();const sleep = () => {return new Promise(res => {setTimeout(function() {res();}, 3000);}); };app.use(async ctx => {if (ctx.request.url === '/api') {await sleep();ctx.body = 'Hello World';} else {ctx.status = 200;ctx.respond = false;fs.createReadStream('./test.html').pipe(ctx.res);} });app.listen(3000);下面是test.html的內(nèi)容
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title> </head> <body><script>fetch('/api').then((res) => {console.log(res, '請(qǐng)求成功');});</script> </body> </html>啟動(dòng)服務(wù)后,我們看下network的內(nèi)容。
我們注意兩個(gè)地方,一個(gè)代表fetch請(qǐng)求,一個(gè)代表請(qǐng)求的延時(shí)時(shí)間,也就是我們定義的三秒
取消fetch
這時(shí)候我們想中斷,就可以這樣做:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title> </head> <body><script>// 增加了如下幾行const controller = new AbortController();const signal = controller.signal;console.log(signal, 'signal的初始狀態(tài)');signal.addEventListener('abort', function (e) {console.log(signal, 'signal的中斷狀態(tài)');});setTimeout(function() {controller.abort();}, 2000);// 增加部分結(jié)束fetch('/api', {signal}).then((res) => {console.log(res, '請(qǐng)求成功');});</script> </body> </html>再次運(yùn)行,我們會(huì)得到如下結(jié)果:
從圖中我們可以很清楚的看到,請(qǐng)求在2s后被終止,請(qǐng)求狀態(tài)變?yōu)閏anceled,然后aborted的狀態(tài)由false轉(zhuǎn)變?yōu)閠rue。
就是這樣,我們對(duì)fetch也進(jìn)行的取消操作,還算是豁然開朗吧。嘻嘻。
兼容性
雖然AbortController已經(jīng)誕生很長(zhǎng)時(shí)間了,但是目前mdn上的定義還是實(shí)驗(yàn)性技術(shù),查看mdn我們可以發(fā)現(xiàn),其實(shí)主流瀏覽器大部分都支持了,如果我們開發(fā)的平臺(tái)很新還是可以使用的,相信不遠(yuǎn)的將來,肯定會(huì)大批量使用。前端的道路也會(huì)越來越順暢!
最后如果這邊文章能幫給你帶來一點(diǎn)幫助,歡迎關(guān)注,點(diǎn)贊,制作不易,與君共勉!
總結(jié)
以上是生活随笔為你收集整理的如何获取.then的返回值_仅仅知道如何终止XHR请求,或许对你来说是不够的!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大数据和人工智能的关系是什么?
- 下一篇: CSS选取子标签元素:nth-child