成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

異步請(qǐng)求與Fetch

vibiu / 3021人閱讀

摘要:再談異步請(qǐng)求語(yǔ)言將任務(wù)的執(zhí)行模式分成兩種同步和異步。通過(guò)對(duì)象及時(shí)監(jiān)聽(tīng)完成事件,執(zhí)行事件回調(diào)函數(shù)不會(huì)堵塞程序運(yùn)行。新的是異步請(qǐng)求的另一種方案,比起其復(fù)雜糅雜的寫法,能更簡(jiǎn)潔的獲取到數(shù)據(jù)。提供了對(duì)和以及其他與網(wǎng)絡(luò)請(qǐng)求有關(guān)的對(duì)象的通用定義。

再談異步請(qǐng)求

Javascript語(yǔ)言將任務(wù)的執(zhí)行模式分成兩種:同步(Synchronous)和異步(Asynchronous)。

在瀏覽器,耗時(shí)很長(zhǎng)的操作都應(yīng)該異步執(zhí)行,避免瀏覽器失去響應(yīng),最好的例子就是Ajax操作。通過(guò)XHRHttpRequest對(duì)象及時(shí)監(jiān)聽(tīng)完成事件,執(zhí)行事件回調(diào)函數(shù)不會(huì)堵塞程序運(yùn)行。

關(guān)于Fetch

Fetch API 提供了一個(gè) JavaScript接口,用于訪問(wèn)和操縱HTTP管道的部分,例如請(qǐng)求和響應(yīng)。它還提供了一個(gè)全局 fetch()方法,該方法提供了一種簡(jiǎn)單,合乎邏輯的方式來(lái)跨網(wǎng)絡(luò)異步獲取資源。這種功能以前是使用 XMLHttpRequest實(shí)現(xiàn)的。Fetch提供了一個(gè)更好的替代方法,可以很容易地被其他技術(shù)使用,例如 Service Workers。Fetch還提供了單個(gè)邏輯位置來(lái)定義其他HTTP相關(guān)概念,例如 CORS和HTTP的擴(kuò)展。

新的Fetch API是XHRHttpRequest異步請(qǐng)求的另一種方案,比起其復(fù)雜糅雜的寫法,fetch能更簡(jiǎn)潔的獲取到數(shù)據(jù)。

XHRHttpRequest使用事件回調(diào)函數(shù)容易進(jìn)入回調(diào)地獄,而Fetch Api接收url參數(shù)返回Promise對(duì)象。

Fetch 提供了對(duì) Request 和 Response (以及其他與網(wǎng)絡(luò)請(qǐng)求有關(guān)的)對(duì)象的通用定義。使之今后可以被使用到更多地應(yīng)用場(chǎng)景中

Fetch的簡(jiǎn)單使用
let url = "http://jsonplaceholder.typicode.com/users"
fetch(url).then((res)=>{
  console.log(res)
}).catch((err)=>{})

將url傳遞給fetch時(shí)會(huì)立即返回一個(gè)promise對(duì)象此時(shí)的狀態(tài)是pending,當(dāng)promise被通過(guò)時(shí)會(huì)返回一個(gè)response對(duì)象。如果我們用習(xí)慣了比如jquery封裝好的ajax方法,很容易會(huì)以為上面的res就是返回的data。

fetch 只有在遇到網(wǎng)絡(luò)錯(cuò)誤的時(shí)候才會(huì) reject 這個(gè) promise,比如用戶斷網(wǎng)或請(qǐng)求地址的域名無(wú)法解析等。只要服務(wù)器能夠返回 HTTP 響應(yīng)(甚至只是 CORS preflight 的 OPTIONS 響應(yīng)),promise 一定是 resolved 的狀態(tài)。

fetch返回Promise對(duì)象

Response簡(jiǎn)介

response.type有以下幾種

basic 標(biāo)準(zhǔn)值,同源響應(yīng)

cors 收到一個(gè)有效的跨域請(qǐng)求

opaque 跨域請(qǐng)求但服務(wù)器沒(méi)有返回cors響應(yīng)頭

但是無(wú)效的跨域請(qǐng)求如果像下面這么寫,其實(shí)根本無(wú)法拿到response對(duì)象

request.mode用于確定跨域請(qǐng)求是否導(dǎo)致有效的響應(yīng)

same-origin 同源情況下才可請(qǐng)求成功,否則拋出錯(cuò)誤

比如在有效的跨域請(qǐng)求設(shè)置這個(gè)模式會(huì)提示
Fetch API cannot load http://jsonplaceholder.typico... Request mode is "same-origin" but the URL"s origin is not same as the request origin file://.

cors: 表示同域和帶有CORS響應(yīng)頭的跨域下可請(qǐng)求成功.

cors-with-forced-preflight: 表示在發(fā)出請(qǐng)求前, 將執(zhí)行preflight檢查.

no-cors: 用于跨域相應(yīng)不帶cors的情況,此時(shí)相應(yīng)類型為opaque

根據(jù)上面的錯(cuò)誤修改fetch的模式就可以返回response對(duì)象了,可以對(duì)比發(fā)現(xiàn)無(wú)效跨域請(qǐng)求并沒(méi)有返回什么有價(jià)值的信息例如url,status,statusText等

reponse.body屬于ReadableStream類型

當(dāng)讀取CSV等大文件時(shí)通過(guò)流來(lái)讀取,可以選擇在讀取到要獲取的數(shù)據(jù)后停止流,而不是獲取到全部響應(yīng)數(shù)據(jù)再去查找。

對(duì)于常用返回的幾種數(shù)據(jù)類型,可以使用blob()、text()、formData()、json(),這幾種方法都會(huì)講body標(biāo)記為已讀數(shù)據(jù),所以想再次獲取的時(shí)候就會(huì)報(bào)錯(cuò)

比如下面的代碼,真實(shí)返回的數(shù)據(jù)不是json類型的,想利用catch方法去捕獲然后再次返回text類型,瀏覽器時(shí)會(huì)報(bào)TypeError: Already read

fetch(url).then(function(response) {
  return response.json().catch(function() {
    return response.text();
  });
});

正確的方式是使用clone()方法先對(duì)數(shù)據(jù)進(jìn)行拷貝,響應(yīng)數(shù)據(jù)通過(guò)clone并不會(huì)被回收,一直留在內(nèi)存中,直至被讀取

fetch(url).then(function(response) {
  return response.clone().json().catch(function() {
    return response.text();
  });
});

Request簡(jiǎn)介

method:設(shè)置請(qǐng)求方法,默認(rèn)GET方法

credentials fetch方法默認(rèn)不發(fā)送cookies,如果遇到401 Unauthorized沒(méi)有權(quán)限問(wèn)題就要看看是否有設(shè)置credentials

omit: 從不發(fā)送cookies.

same-origin: 只有當(dāng)URL與響應(yīng)腳本同源才發(fā)送cookies.

include: 總是發(fā)送cookies, 即使來(lái)自跨域的請(qǐng)求

默認(rèn)情況下請(qǐng)求不帶coookie

cache 設(shè)置緩存,跟XHR對(duì)比在請(qǐng)求時(shí)就可以控制緩存,雖然這是有爭(zhēng)議的,因?yàn)檫@暴露了用戶歷史記錄

default

如果是最新的資源,則返回緩存

如果資源已過(guò)期則向服務(wù)器發(fā)出條件請(qǐng)求;如果服務(wù)器指示資源沒(méi)有改變則返回緩存;否則從服務(wù)器中下載,并更新緩存。

如果沒(méi)有找到緩存則發(fā)出正常情求,但不緩存資源。

no-store 直接從服務(wù)器獲取資源并且不會(huì)將資源緩存

reload 直接從服務(wù)器獲取資源,并且緩存資源

no-cache

如果資源有效或者過(guò)期,瀏覽器會(huì)發(fā)出一個(gè)條件請(qǐng)求,如果服務(wù)器返回沒(méi)有改變,則返回緩存,否則,重新獲取資源并更新緩存

如果不存在資源則瀏覽器發(fā)出正常請(qǐng)求下載并更新緩存

force-cache

如果有緩存直接返回緩存,否則下載更新資源

only-if-cached

如果有緩存直接返回緩存,否則瀏覽器返回錯(cuò)誤

XHR和Fetch其他的對(duì)比

fetch沒(méi)有xhr中的abort()方法來(lái)中斷請(qǐng)求

fetch沒(méi)有progress進(jìn)度事件監(jiān)聽(tīng)數(shù)據(jù),但是你可以通過(guò)獲取content-length計(jì)算進(jìn)度

XHR open方法有最后一個(gè)參數(shù)設(shè)為false的時(shí)候是同步請(qǐng)求,fetch沒(méi)有提供同步請(qǐng)求的方法,但同步請(qǐng)求并不常用

fetch 并沒(méi)有像XHR的timeout屬性來(lái)設(shè)置延時(shí)

Fetch實(shí)踐體驗(yàn)

習(xí)慣了像是vue-resource等插件封裝好的get,post方法,在使用fetch的時(shí)候很容易會(huì)被它看似簡(jiǎn)潔的api給迷惑

fetch兼容性問(wèn)題

我們需要引入fetch 的polyfill,扒開(kāi)源碼我們可以發(fā)現(xiàn)實(shí)現(xiàn)原理還是建立在XMLHttpRequest上的,但是由于polyfill要實(shí)現(xiàn)fetch如Blob類文件對(duì)象等,在safari和ie上還是有兼容性問(wèn)題的

參數(shù)傳遞問(wèn)題

在get請(qǐng)求方式中,我們還是只能像xhr那樣以拼接url字符串的方式來(lái)傳遞,這與fetch看起來(lái)簡(jiǎn)潔的api有點(diǎn)不符。

雖然原生的URLSearchParams 接口定義了用來(lái)處理 URL 參數(shù)串的方法。但是這個(gè)api目前兼容性也是不怎么好

var paramsString = "q=URLUtils.searchParams&topic=api"
var searchParams = new URLSearchParams(paramsString);
searchParams.append("topic", "webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"

在post請(qǐng)求中,數(shù)據(jù)要以body字段來(lái)傳遞參數(shù),也就是說(shuō)我們要常用的json格式要經(jīng)過(guò)下面格式的轉(zhuǎn)換,就像XMLHttpRequest那樣

body 可以是以下任何一種類型的實(shí)例:

ArrayBuffer
ArrayBufferView (Uint8Array and friends)
Blob/File
string
URLSearchParams
FormData

響應(yīng)數(shù)據(jù)的問(wèn)題

在回調(diào)函數(shù)中我們首先接受到的是response對(duì)象,由于body是ReadableStream類型,幾乎很難預(yù)先判斷數(shù)據(jù)是什么類型,也就很難判斷是到底用text()、json()方法解析數(shù)據(jù)

response對(duì)象有一個(gè)bodyUsed的屬性初始是false,調(diào)用text()、json()等方法會(huì)讀取Response對(duì)象并且將它設(shè)置為已讀,這時(shí)bodyUsed為true

bodyUsed初始值為false

- 解決辦法有兩種但都有一定的不足
     1.是通過(guò)clone加catch方式找到正確的輸出方式,但是要注意調(diào)用方法的順序,不然一個(gè)json有可能最后還是以text的方式解析,還要注意的是最后要將response的數(shù)據(jù)回收或者讀取,因?yàn)閏lone方法的讀取并不影響原來(lái)的reponse對(duì)象
fetch(url).then(function(response) {
      return response.json().catch(function() {
         return response.text();
      });
});
  2.是通過(guò)判斷content-type的方式,如果已知的返回格式不多的情況下用還是不錯(cuò)的選擇
fetch(url).then(function(response) {
      if (response.headers.get("Content-Type") === "application/json") {
        return response.json();
      }
      return response.text();
});
小結(jié)

基于promise的fecth方法可以讓我們遠(yuǎn)離回調(diào)地獄而不需要其他的封裝。

fetch 將 response.body 設(shè)計(jì)成 ReadableStream 其實(shí)是非常有前瞻性的,這種設(shè)計(jì)讓你在請(qǐng)求大體積文件時(shí)變得非常有用。

參考資料:https://jakearchibald.com/201...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83899.html

相關(guān)文章

  • 對(duì)python并發(fā)編程的思考

    摘要:我們以請(qǐng)求網(wǎng)絡(luò)服務(wù)為例,來(lái)實(shí)際測(cè)試一下加入多線程之后的效果。所以,執(zhí)行密集型操作時(shí),多線程是有用的,對(duì)于密集型操作,則每次只能使用一個(gè)線程。說(shuō)到這里,對(duì)于密集型,可以使用多線程或者多進(jìn)程來(lái)提高效率。 為了提高系統(tǒng)密集型運(yùn)算的效率,我們常常會(huì)使用到多個(gè)進(jìn)程或者是多個(gè)線程,python中的Threading包實(shí)現(xiàn)了線程,multiprocessing 包則實(shí)現(xiàn)了多進(jìn)程。而在3.2版本的py...

    sshe 評(píng)論0 收藏0
  • ES6 Fetch API HTTP請(qǐng)求實(shí)用指南

    摘要:例子張三刪除用戶為了刪除用戶,我們首先需要定位用戶,然后我們定義方法類型。例子張三結(jié)論現(xiàn)在,你已基本了解如何使用的從服務(wù)器檢索或操作資源,以及如何處理。您可以使用本文作為如何構(gòu)建操作的請(qǐng)求的指南。 showImg(https://segmentfault.com/img/bVbjxqh?w=1000&h=562); 本次將介紹如何使用Fetch API(ES6 +)對(duì)REST API的...

    Sunxb 評(píng)論0 收藏0
  • JavaScript 異步進(jìn)化史

    摘要:簽訂協(xié)議的兩方分別是異步接口和。在異步函數(shù)中,使用異常捕獲的方案,代替了的異常捕獲的方案。需要注意的是,在異步函數(shù)中使異步函數(shù)用時(shí)要使用,不然異步函會(huì)被同步執(zhí)行。 同步與異步 通常,代碼是由上往下依次執(zhí)行的。如果有多個(gè)任務(wù),就必需排隊(duì),前一個(gè)任務(wù)完成,后一個(gè)任務(wù)才會(huì)執(zhí)行。這種執(zhí)行模式稱之為: 同步(synchronous) 。新手容易把計(jì)算機(jī)用語(yǔ)中的同步,和日常用語(yǔ)中的同步弄混淆。如,...

    luzhuqun 評(píng)論0 收藏0
  • tornado6python3.7 異步新姿勢(shì)

    摘要:這是我重新復(fù)習(xí)的原因放棄了之前自己實(shí)現(xiàn)的全面擁抱的這個(gè)改動(dòng)是非常大的而且閱讀的源碼可以發(fā)現(xiàn)其中大部分函數(shù)都支持了類型檢驗(yàn)和返回值提示值得閱讀 廢話不多說(shuō),直接上代碼 __auth__ = aleimu __doc__ = 學(xué)習(xí)tornado6.0+ 版本與python3.7+ import time import asyncio import tornado.gen import t...

    maxmin 評(píng)論0 收藏0
  • Fluent Fetcher: 重構(gòu)基于 Fetch 的 JavaScript 網(wǎng)絡(luò)請(qǐng)求庫(kù)

    摘要:重構(gòu)基于的網(wǎng)絡(luò)請(qǐng)求庫(kù)從屬于筆者的開(kāi)發(fā)基礎(chǔ)與工程實(shí)踐系列文章與項(xiàng)目,記述了筆者對(duì)內(nèi)部使用的封裝庫(kù)的設(shè)計(jì)重構(gòu)與實(shí)現(xiàn)過(guò)程?;臼褂冒姹局械闹?,最核心的設(shè)計(jì)變化在于將請(qǐng)求構(gòu)建與請(qǐng)求執(zhí)行剝離了開(kāi)來(lái)。而函數(shù)則負(fù)責(zé)執(zhí)行請(qǐng)求,并且返回經(jīng)過(guò)擴(kuò)展的對(duì)象。 Fluent Fetcher: 重構(gòu)基于 Fetch 的 JavaScript 網(wǎng)絡(luò)請(qǐng)求庫(kù)從屬于筆者的 Web 開(kāi)發(fā)基礎(chǔ)與工程實(shí)踐系列文章與項(xiàng)目,記述了...

    Yangder 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<