Promise,Ajax,fetch

來源:互聯網
上載者:User

一、Promise相關

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

http://liubin.org/promises-book/#chapter1-what-is-promise

new Promise(    /* executor:executor是一個帶有resolve和reject兩個參數的函數 。 */    function(resolve, reject) {...});
resolve 函數被調用時將promise的狀態改為fulfilled(完成)
reject 函數被調用時將promise的狀態改為rejected(失敗)。

一個 Promise有以下三種狀態:
pending: 初始狀態,不是成功或失敗狀態。
fulfilled: 意味著操作成功完成。
rejected: 意味著操作失敗。


pending 狀態的 Promise 對象某個 狀態並傳遞一個值給相應的狀態處理方法時,Promise 對象的 then 方法綁定的處理方法(handlers )就會被調用(then方法包含兩個參數:onfulfilled 和 onrejected,它們都是 Function 類型。當Promise狀態為fulfilled時,調用 then 的 onfulfilled 方法,當Promise狀態為rejected時,調用 then 的 onrejected 方法, 所以在非同步作業的完成和綁定處理方法之間不存在競爭)。


Promise.all(iterable)
iterable參數對象裡所有的promise對象都成功的時候才會觸發成功,有一個失敗則立即觸發該promise對象的失敗。這個新的promise對象在觸發成功狀態以後,會把一個包含iterable裡所有promise傳回值的數組作為成功回調的傳回值,順序跟iterable的順序保持一致;如果這個新的promise對象觸發了失敗狀態,它會把iterable裡第一個觸發失敗的promise對象的錯誤資訊作為它的失敗錯誤資訊。Promise.all方法常被用於處理多個promise對象的狀態集合。
Promise.race(iterable)
當iterable參數裡的任意一個子promise被成功或失敗後,父promise馬上也會用子promise的成功傳回值或失敗詳情作為參數調用父promise綁定的相應控制代碼,並返回該promise對象。
Promise.reject(reason)
返回一個狀態為失敗的Promise對象,並將給定的失敗資訊傳遞給對應的處理方法
Promise.resolve(value)
返回一個狀態由給定value決定的Promise對象。如果該值是一個Promise對象,則直接返回該對象;如果該值是thenable(即,帶有then方法的對象),返回的Promise對象的最終狀態由then方法執行決定;否則的話(該value為空白,基本類型或者不帶then方法的對象),返回的Promise對象狀態為fulfilled,並且將該value傳遞給對應的then方法。通常而言,如果你不知道一個值是否是Promise對象,使用Promise.resolve(value) 來返回一個Promise對象,這樣就能將該value以Promise對象形式使用。

栗子:

var myFirstPromise = new Promise(function(resolve, reject){    //當非同步代碼執行成功時,我們才會調用resolve(...), 當非同步代碼失敗時就會調用reject(...)    //在本例中,我們使用setTimeout(...)來類比非同步代碼,實際編碼時可能是XHR請求或是HTML5的一些API方法.    setTimeout(function(){        resolve("成功!"); //代碼正常執行。    }, 250);});myFirstPromise.then(function(successMessage){    //successMessage的值是上面調用resolve(...)方法傳入的值.    //successMessage參數不一定非要是字串類型,這裡只是舉個例子    console.log("Yay! " + successMessage);});


二、Fetch

https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalFetch/fetch
fetch() 方法用於發起擷取資源的請求。它返回一個 promise,這個 promise 會在請求響應後被 resolve,並傳回 Response 對象。
當遇到網路錯誤時,fetch() 返回的 promise 會被 reject,並傳回 TypeError,雖然這也可能因為許可權或其它問題導致。成功的 fetch() 檢查不僅要包括 promise 被 resolve,還要包括 Response.ok 屬性為 true。HTTP 404 狀態並不被認為是網路錯誤。


Promise<Response> fetch(input[, init]);
input可能是個 USVString 字串,包含要擷取資源的 URL;也有可能是個Request對象
FetchAPI的Request 介面用來表示資源請求。
屬性:
Request.method:請求使用的方法 (GET, POST, 等.)
Request.url:請求使用的 URL。
Request.headers:請求所關聯的 Headers 對象。

方法:
Request.clone():建立當前request的副本。

傳回值
一個 Promise,resolve 時回傳 Response 對象。

var myImage = document.querySelector('img');//HTML5新增方法var myRequest = new Request('flowers.jpg');//var myRequest = new Request('flowers.jpg',myInit);fetch(myRequest).then(function(response) {  return response.blob();}).then(function(response) {  var objectURL = URL.createObjectURL(response);  myImage.src = objectURL;});

var myImage = document.querySelector('img');var myHeaders = new Headers();myHeaders.append('Content-Type', 'image/jpeg');var myInit = { method: 'GET',               headers: myHeaders,               mode: 'cors',               cache: 'default' };var myRequest = new Request('flowers.jpg');fetch(myRequest,myInit).then(function(response) {  ... });

Fetch 優點主要有:
文法簡潔,更加語義化
基於標準 Promise 實現,支援 async/await
同構方便,使用 isomorphic-fetch
Fetch 常見坑
Fetch 請求預設是不帶 cookie 的,需要設定 fetch(url, {credentials: 'include'})
伺服器返回 400,500 錯誤碼時並不會 reject,只有網路錯誤這些導致請求不能完成時,fetch 才會被 reject。
IE 使用原則
所有版本的 IE 均不支援原生 Fetch,fetch-ie8 會自動使用 XHR 做 polyfill。但在跨域時有個問題需要處理。
IE8, 9 的 XHR 不支援 CORS 跨域,雖然提供 XDomainRequest,但這個東西就是玩具,不支援傳 Cookie。如果介面需要許可權驗證,還是乖乖地使用 jsonp 吧。

三、Ajax和fetch比較

fetch被稱為下一代ajax技術,與 Ajax 不同的是,它的 API 不是事件機制,而採用了 Promise 方式處理,目前還不是 W3C 規範

Ajax的本質是使用XMLHttpRequest對象來請求資料
fetch 是全域量 window 的一個方法,它的主要特點有:
1、第一個參數是URL:
2、第二個是選擇性參數,可以控制不同配置的 init 對象
3、使用了 JavaScript Promises 來處理結果/回調:

區別:
1、從 fetch()返回的 Promise 將不會拒絕HTTP錯誤狀態, 即使響應是一個 HTTP 404 或 500。相反,它會正常解決 (其中ok狀態設定為false), 並且僅在網路故障時或任何阻止請求完成時,它才會拒絕。
2、預設情況下, fetch在服務端不會發送或接收任何 cookies, 如果網站依賴於維護一個使用者會話,則導致未經認證的請求(要發送 cookies,必鬚髮送憑據頭).
如果想要在同域中自動發送cookie,加上 credentials 的 same-origin 選項

fetch(url, {  credentials: ’same-origin'})
same-origin值使得fetch處理Cookie與XMLHttpRequest類似。 否則,Cookie將不會被發送,導致這些請求不保留認證會話。
對於CORS請求,使用include值允許將憑據發送到其他域:
fetch(url, {  credentials: 'include'})

四、async/await

ES7的Async/Await。

轉自:http://cnodejs.org/topic/5640b80d3a6aa72c5e0030b6

栗子:

這裡我們要實現一個暫停功能,輸入N毫秒,則停頓N毫秒後才繼續往下執行。

var sleep = function (time) {    return new Promise(function (resolve, reject) {        setTimeout(function () {            resolve();        }, time);    })};var start = async function () {    try {// 在這裡使用起來就像同步代碼那樣直觀        console.log('start');        await sleep(3000); // 這裡得到了一個返回錯誤                // 所以以下代碼不會被執行了        console.log('end');    } catch (err) {        console.log(err); // 這裡捕捉到錯誤 `error`    }};start();

轉自:https://segmentfault.com/a/1190000007535316
async 表示這是一個async函數,await只能用在這個函數裡面。await 表示在這裡等待promise返回結果了,再繼續執行。await 後面跟著的應該是一個promise對象(當然,其他傳回值也沒關係,只是會立即執行,不過那樣就沒有意義了…)
async 用於申明一個 function 是非同步,而 await 用於等待一個非同步方法呼叫執行完成。
一般來說,都認為 await 是在等待一個 async 函數完成。不過按文法說明,await 等待的是一個運算式,這個運算式的計算結果是 Promise 對象或者其它值(換句話說,就是沒有特殊限定)。因為 async 函數返回一個 Promise 對象,所以 await 可以用於等待一個 async 函數的傳回值——這也可以說是 await 在等 async 函數,但要清楚,它等的實際是一個傳回值。注意到 await 不僅僅用於等 Promise 對象,它可以等任意運算式的結果await 等到了它要等的東西,一個 Promise 對象,或者其它值,然後呢。我不得不先說,await 是個運算子,用於組成運算式,await 運算式的運算結果取決於它等的東西。       如果它等到的不是一個 Promise 對象,那 await 運算式的運算結果就是它等到的東西。       如果它等到的是一個 Promise 對象,await 就忙起來了,它會阻塞後面的代碼,等著 Promise 對象 resolve,然後得到 resolve 的值,作為 await 運算式的運算結果。async/await 的優勢在於處理 then 鏈單一的 Promise 鏈並不能發現 async/await 的優勢,但是,如果需要處理由多個 Promise 組成的 then 鏈的時候,優勢就能體現出來了(很有意思,Promise 通過 then 鏈來解決多層回調的問題,現在又用 async/await 來進一步最佳化它)。
栗子:
假設一個業務,分多個步驟完成,每個步驟都是非同步,而且依賴於上一個步驟的結果。我們仍然用 setTimeout 來類比非同步作業:

function doIt() {    console.time("doIt");    const time1 = 300;    step1(time1)        .then(time2 => step2(time2))        .then(time3 => step3(time3))        .then(result => {            console.log(`result is ${result}`);            console.timeEnd("doIt");        });}doIt();// c:\var\test>node --harmony_async_await .// step1 with 300// step2 with 500// step3 with 700// result is 900// doIt: 1507.251ms

async function doIt() {    console.time("doIt");    const time1 = 300;    const time2 = await step1(time1);    const time3 = await step2(time2);    const result = await step3(time3);    console.log(`result is ${result}`);    console.timeEnd("doIt");}doIt();


厲害了


 
 
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.