摘要:結(jié)果證明,對(duì)于以上瀏覽器,在生產(chǎn)環(huán)境使用是可行的。后面可以跟對(duì)象,表示等待才會(huì)繼續(xù)向下執(zhí)行,如果被或拋出異常則會(huì)被外面的捕獲。,,都是現(xiàn)在和未來解決異步的標(biāo)準(zhǔn)做法,可以完美搭配使用。這也是使用標(biāo)準(zhǔn)一大好處。只允許外部傳入成功或失敗后的回調(diào)。
原諒我做一次標(biāo)題黨,Ajax 不會(huì)死,傳統(tǒng) Ajax 指的是 XMLHttpRequest(XHR),未來現(xiàn)在已被 Fetch 替代。
最近把阿里一個(gè)千萬級(jí) PV 的數(shù)據(jù)產(chǎn)品全部由 jQuery 的 $.ajax 遷移到 Fetch,上線一個(gè)多月以來運(yùn)行非常穩(wěn)定。結(jié)果證明,對(duì)于 IE8+ 以上瀏覽器,在生產(chǎn)環(huán)境使用 Fetch 是可行的。
由于 Fetch API 是基于 Promise 設(shè)計(jì),有必要先學(xué)習(xí)一下 Promise,推薦閱讀 MDN Promise 教程。舊瀏覽器不支持 Promise,需要使用 polyfill es6-promise 。
本文不是 Fetch API 科普貼,其實(shí)是講異步處理和 Promise 的。Fetch API 很簡單,看文檔很快就學(xué)會(huì)了。推薦 MDN Fetch 教程 和 萬能的WHATWG Fetch 規(guī)范
Why FetchXMLHttpRequest 是一個(gè)設(shè)計(jì)粗糙的 API,不符合關(guān)注分離(Separation of Concerns)的原則,配置和調(diào)用方式非?;靵y,而且基于事件的異步模型寫起來也沒有現(xiàn)代的 Promise,generator/yield,async/await 友好。
Fetch 的出現(xiàn)就是為了解決 XHR 的問題,拿例子說明:
使用 XHR 發(fā)送一個(gè) json 請(qǐng)求一般是這樣:
var xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.responseType = "json"; xhr.onload = function() { console.log(xhr.response); }; xhr.onerror = function() { console.log("Oops, error"); }; xhr.send();
使用 Fetch 后,頓時(shí)看起來好一點(diǎn)
fetch(url).then(function(response) { return response.json(); }).then(function(data) { console.log(data); }).catch(function(e) { console.log("Oops, error"); });
使用 ES6 的 箭頭函數(shù) 后:
fetch(url).then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("Oops, error", e))
現(xiàn)在看起來好很多了,但這種 Promise 的寫法還是有 Callback 的影子,而且 promise 使用 catch 方法來進(jìn)行錯(cuò)誤處理的方式有點(diǎn)奇怪。不用急,下面使用 async/await 來做最終優(yōu)化:
注:async/await 是非常新的 API,屬于 ES7,目前尚在 Stage 1(提議) 階段,這是它的完整規(guī)范。使用 Babel 開啟 runtime 模式后可以把 async/await 無痛編譯成 ES5 代碼。也可以直接使用 regenerator 來編譯到 ES5。
try { let response = await fetch(url); let data = response.json(); console.log(data); } catch(e) { console.log("Oops, error", e); } // 注:這段代碼如果想運(yùn)行,外面需要包一個(gè) async function
duang~~ 的一聲,使用 await 后,寫異步代碼就像寫同步代碼一樣爽。await 后面可以跟 Promise 對(duì)象,表示等待 Promise resolve() 才會(huì)繼續(xù)向下執(zhí)行,如果 Promise 被 reject() 或拋出異常則會(huì)被外面的 try...catch 捕獲。
Promise,generator/yield,await/async 都是現(xiàn)在和未來 JS 解決異步的標(biāo)準(zhǔn)做法,可以完美搭配使用。這也是使用標(biāo)準(zhǔn) Promise 一大好處。最近也把項(xiàng)目中使用第三方 Promise 庫的代碼全部轉(zhuǎn)成標(biāo)準(zhǔn) Promise,為以后全面使用 async/await 做準(zhǔn)備。
另外,F(xiàn)etch 也很適合做現(xiàn)在流行的同構(gòu)應(yīng)用,有人基于 Fetch 的語法,在 Node 端基于 http 庫實(shí)現(xiàn)了 node-fetch,又有人封裝了用于同構(gòu)應(yīng)用的 isomorphic-fetch。
注:同構(gòu)(isomorphic/universal)就是使前后端運(yùn)行同一套代碼的意思,后端一般是指 NodeJS 環(huán)境。
總結(jié)一下,F(xiàn)etch 優(yōu)點(diǎn)主要有:
語法簡潔,更加語義化
基于標(biāo)準(zhǔn) Promise 實(shí)現(xiàn),支持 async/await
同構(gòu)方便,使用 isomorphic-fetch
Fetch 啟用方法下面是重點(diǎn)↓↓↓
先看一下 Fetch 原生支持率:
原生支持率并不高,幸運(yùn)的是,引入下面這些 polyfill 后可以完美支持 IE8+ :
由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
引入 Promise 的 polyfill: es6-promise
引入 fetch 探測(cè)庫:fetch-detector
引入 fetch 的 polyfill: fetch-ie8
可選:如果你還使用了 jsonp,引入 fetch-jsonp
可選:開啟 Babel 的 runtime 模式,現(xiàn)在就使用 async/await
Fetch polyfill 的基本原理是探測(cè)是否存在 window.fetch 方法,如果沒有則用 XHR 實(shí)現(xiàn)。這也是 github/fetch 的做法,但是有些瀏覽器(Chrome 45)原生支持 Fetch,但響應(yīng)中有中文時(shí)會(huì)亂碼,老外又不太關(guān)心這種問題,所以我自己才封裝了 fetch-detector 和 fetch-ie8 只在瀏覽器穩(wěn)定支持 Fetch 情況下才使用原生 Fetch。這些庫現(xiàn)在每天有幾千萬個(gè)請(qǐng)求都在使用,絕對(duì)靠譜!
終于,引用了這一堆 polyfill 后,可以愉快地使用 Fetch 了。但要小心,下面有坑:
Fetch 常見坑Fetch 請(qǐng)求默認(rèn)是不帶 cookie 的,需要設(shè)置 fetch(url, {credentials: "include"})
服務(wù)器返回 400,500 錯(cuò)誤碼時(shí)并不會(huì) reject,只有網(wǎng)絡(luò)錯(cuò)誤這些導(dǎo)致請(qǐng)求不能完成時(shí),fetch 才會(huì)被 reject。
竟然沒有提到 IE,這實(shí)在太不科學(xué)了,現(xiàn)在來詳細(xì)說下 IE
IE 使用策略所有版本的 IE 均不支持原生 Fetch,fetch-ie8 會(huì)自動(dòng)使用 XHR 做 polyfill。但在跨域時(shí)有個(gè)問題需要處理。
IE8, 9 的 XHR 不支持 CORS 跨域,雖然提供 XDomainRequest,但這個(gè)東西就是玩具,不支持傳 Cookie!如果接口需要權(quán)限驗(yàn)證,還是乖乖地使用 jsonp 吧,推薦使用 fetch-jsonp。如果有問題直接提 issue,我會(huì)第一時(shí)間解決。
標(biāo)準(zhǔn) Promise 的不足由于 Fetch 是典型的異步場(chǎng)景,所以大部分遇到的問題不是 Fetch 的,其實(shí)是 Promise 的。ES6 的 Promise 是基于 Promises/A+ 標(biāo)準(zhǔn),為了保持簡單簡潔,只提供極簡的幾個(gè) API。如果你用過一些牛 X 的異步庫,如 jQuery(不要笑) 、Q.js 或者 RSVP.js,可能會(huì)感覺 Promise 功能太少了。
沒有 DeferredDeferred 可以在創(chuàng)建 Promise 時(shí)可以減少一層嵌套,還有就是跨方法使用時(shí)很方便。
ECMAScript 11 年就有過 Deferred 提案,但后來沒被接受。其實(shí)用 Promise 不到十行代碼就能實(shí)現(xiàn) Deferred:es6-deferred?,F(xiàn)在有了 async/await,generator/yield 后,deferred 就沒有使用價(jià)值了。
標(biāo)準(zhǔn) Promise 沒有提供獲取當(dāng)前狀態(tài) rejected 或者 resolved 的方法。只允許外部傳入成功或失敗后的回調(diào)。我認(rèn)為這其實(shí)是優(yōu)點(diǎn),這是一種聲明式的接口,更簡單。
缺少其它一些方法:always,progress,finallyalways 可以通過在 then 和 catch 里重復(fù)調(diào)用方法實(shí)現(xiàn)。finally 也類似。progress 這種進(jìn)度通知的功能還沒有用過,暫不知道如何替代。
最后Fetch 替換 XHR 只是時(shí)間問題,現(xiàn)在看到國外很多新的庫都默認(rèn)使用了 Fetch。
最后再做一個(gè)大膽預(yù)測(cè):由于 async/await 這類新異步語法的出現(xiàn),第三方的 Promise 類庫會(huì)逐漸被標(biāo)準(zhǔn) Promise 替代,使用 polyfill 是現(xiàn)在比較明智的做法。
轉(zhuǎn)至我的博客,原文地址:https://github.com/camsong/blog/issues/2
想不想加入阿里巴巴一起玩 ES7,React,F(xiàn)RP 等最新技術(shù),歡迎簡歷到 neosoyn@gmail.com
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/86024.html
摘要:的在成為標(biāo)準(zhǔn)之后,會(huì)越來越方便開發(fā)人員與相比,更加簡潔,資源獲取方式比更優(yōu)雅。。方法返回的是對(duì)象,使用深入淺出傳統(tǒng)已死,永生鏈接描述 Fetch API提供了一個(gè)fetch()方法,它被定義在BOM的window對(duì)象中,你可以用它來發(fā)起HTTP請(qǐng)求。 該方法返回的是一個(gè)Promise對(duì)象,讓你能夠?qū)φ?qǐng)求的返回結(jié)果進(jìn)行處理(通過then方法進(jìn)行連續(xù)調(diào)用,減少嵌套。ES6的Promise在...
摘要:后面可以跟對(duì)象,表示等待才會(huì)繼續(xù)下去執(zhí)行,如果被或拋出異常則會(huì)被外面的捕獲。沒有獲取狀態(tài)方法,標(biāo)準(zhǔn)沒有提供獲取當(dāng)前狀態(tài)或者的方法。只允許外部傳入成功或失敗后的回調(diào)。這種進(jìn)度通知的功能還沒有用過,暫不知道如何替代。 始終不是很懂fetch的作用,然后查了很多資料,看了一篇不錯(cuò)的文章,結(jié)合自己之前學(xué)習(xí)的Promise,然后做一篇文章,稍微記錄一下。傳統(tǒng) Ajax 已死,F(xiàn)etch 永生 雖...
首先聲明一下,本文不是要講解fetch的具體用法,不清楚的可以參考MDN fetch教程。 引言 說道fetch就不得不提XMLHttpRequest了,XHR在發(fā)送web請(qǐng)求時(shí)需要開發(fā)者配置相關(guān)請(qǐng)求信息和成功后的回調(diào),盡管開發(fā)者只關(guān)心請(qǐng)求成功后的業(yè)務(wù)處理,但是也要配置其他繁瑣內(nèi)容,導(dǎo)致配置和調(diào)用比較混亂,也不符合關(guān)注分離的原則;fetch的出現(xiàn)正是為了解決XHR存在的這些問題。例如下面代碼: f...
摘要:我們都知道因?yàn)橥床呗缘膯栴},瀏覽器的請(qǐng)求是可能隨便跨域的一定要有跨域頭或者借助,但是,中可以設(shè)置為不跨域,如下所示這樣之后我們會(huì)得到一個(gè)為的返回。 免費(fèi)幫忙內(nèi)推阿里等各大IT公司的崗位,有興趣可以帶簡歷加微信angeltune 引言 前端技術(shù)真是一個(gè)發(fā)展飛快的領(lǐng)域,我三年前入職的時(shí)候只有原生XHR和Jquery ajax,我們還曾被JQuery 1.9版本版本以下不支持大文件請(qǐng)求這個(gè)...
摘要:讓應(yīng)用程序擁有異步讀取存儲(chǔ)在用戶計(jì)算機(jī)上文件或原始數(shù)據(jù)緩沖區(qū)的能力,使用或?qū)ο笾付ㄒx取的文件或數(shù)據(jù)。對(duì)象用來表示通用的固定長度的原始二進(jìn)制數(shù)據(jù)緩沖區(qū)。事實(shí)上,沒有名為的全局對(duì)象,也沒有一個(gè)名為的構(gòu)造函數(shù)。 Ajax 即 Asynchronous Javascript And XML (異步 JavaScript 和 XML),是指一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)。在無需重新加載整...
閱讀 3107·2021-11-02 14:40
閱讀 889·2019-08-30 15:53
閱讀 1343·2019-08-30 15:53
閱讀 3316·2019-08-30 13:53
閱讀 3375·2019-08-29 12:50
閱讀 1194·2019-08-26 13:49
閱讀 1928·2019-08-26 12:20
閱讀 3727·2019-08-26 11:33