始終不是很懂fetch的做用,而後查了不少資料,看了一篇不錯的文章,結合本身以前學習的Promise,而後作一篇文章,稍微記錄一下。
傳統 Ajax 已死,Fetch 永生git
雖然標題感受比較大,而後指出了XMLHttpRequest的侷限性。XMLHttpRequest是一個設計粗糙的API,不符合關注分離的原則,配置和調用方式也很混亂,並且基於事件的異步模式沒有Promise友好。雖然我也沒有以爲這樣的理由足夠強大到能夠把Ajax逼死,可是畢竟流行是一種趨勢。隨着ES6時代的全面爆發,相信fetch的時代也將不會很遠了。es6
如今來比較爲了發起一個異步請求,兩種寫法的區別。github
用XHR發送一個json請求通常是這樣的:json
var xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.responseType = 'json'; xhr.onload = function(){ console.log(xhr.response); }; xhr.onerror = function(){ console.log("error") } xhr.send();
用fetch實現的方式:服務器
fetch(url).then(function(response){ return response.json(); }).then(function(data){ console.log(data) }).catch(function(e){ console.log("error") })
使用ES6的箭頭函數後cookie
fetch(url).then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("error"))
也能夠用async/await的方式網絡
try{ let response = await fetch(url); let data = await response.json(); console.log(data); } catch(e){ console.log("error") }
用了await後,寫異步代碼感受像同步代碼同樣爽。await後面能夠跟Promise對象,表示等待Promise resolve()纔會繼續下去執行,若是Promise被reject()或拋出異常則會被外面的try...catch捕獲。異步
fetch的主要優勢是async
語法簡潔,更加語義化函數
基於標準的Promise實現,支持async/await
同構方便
可是也有它的不足
fetch請求默認是不帶cookie的,須要設置fetch(url, {credentials: 'include'})
服務器返回400,500這樣的錯誤碼時不會reject,只有網絡錯誤這些致使請求不能完成時,fetch纔會被reject.
Deferred 能夠在建立 Promise 時能夠減小一層嵌套,還有就是跨方法使用時很方便。
ECMAScript 11 年就有過 Deferred 提案,但後來沒被接受。其實用 Promise 不到十行代碼就能實現 Deferred:es6-deferred。如今有了 async/await,generator/yield 後,deferred 就沒有使用價值了。
標準 Promise 沒有提供獲取當前狀態 rejected 或者 resolved 的方法。只容許外部傳入成功或失敗後的回調。我認爲這實際上是優勢,這是一種聲明式的接口,更簡單。
缺乏其它一些方法:always,progress,finally
always 能夠經過在 then 和 catch 裏重複調用方法實現。finally 也相似。progress 這種進度通知的功能尚未用過,暫不知道如何替代。
Fetch 和 Promise 同樣,一旦發起,不能中斷,也不會超時,只能等待被 resolve 或 reject。