在練習fetch
之前,讓我們先談談promise
,再PWAs裡面,很常會看到promise
的蹤影,像在一開始註冊的時候,就會回傳promise
型別,如果成功就會執行then
,因此,就來複習一下用法吧!
navigator.serviceWorker.register('/service-worker.js')
.then(function(){
console.log('Service Worker 註冊成功');
});
前面說過Js是一條執行序,因此我們預期當我們有A、B和C三個任務,執行時,應該是依序A、B和C執行,但實際上Javascript上是以非同步的方式執行,畫了一張示意圖如下。
箭頭上方的是我們原本預期會依序執行的方式,但實際上,javascript會以非同步的方式先載入,再等程式執行完後回傳。
setTimeout(function(){
resolve('三秒過後執行');
},3000);
console.log('再Timeout之後執行');
以一個簡單的測試方式,原先預期的結果應該是
三秒過後執行
再Timeout之後執行
實際是
再Timeout之後執行
三秒過後執行
我們將上面的測試以Promise
的方式實作
var promise = new Promise(function(resolve,reject){
setTimeout(function(){
resolve('三秒過後執行');
},3000);
});
promise.then(function(result){
console.log(result);
});
console.log('再Timeout之後執行');
新增Promise
時,會發現function
中傳了resolve
和reject
,resolve
代表當成是執行成功時會回傳的東西,而reject
代表在過程中發生錯誤時,會回傳的物件。Promise
本身回傳的結果也是以非同步的方式進行,但是它有趣的一點是能將很多非同步的事情,串成一條龍,讓你能有順序的方式執行。
為了驗證一下,所以將字串「再Timeout之後執行」的程式碼接再then
後面。
promise.then(function(result){
console.log(result);
return result;
}).then(function(result){
if(result != undefined && result != '')
console.log('再Timeout之後執行');
});
如上面的執行結果,3秒後,Promise
將字串回傳了第一個then
,印出後接著回傳結過到下一個then
,才印出「再Timeout之後執行」。
而如果要抓錯誤訊息了話,試著將resolve
改成reject
reject({code: 500,message: '發生錯誤'});
點then
後面接catch
,就可以接到錯誤訊息了。
promise.then(function(result){
console.log(result);
return result;
}).then(function(result){
if(result != undefined && result != '')
console.log('再Timeout之後執行');
}).catch(function(err){
console.log(err.code+' '+err.message);
});
以上就是Promise
最基本的用法,接著就回到fetch
的話題吧~
為了體驗fetch
的效果,可以到http://httpbin.org/
有許多可以讓我們測試get
或post
的資料,以下就來測試
抓取現在的ip
位置做測試,
fetch('http://httpbin.org/ip')
.then(function(response){
console.log(response);
return response.json();
})
.then(function(data){
console.log(data);
})
.catch(function(err){
console.log(err);
});
給了fetch
要抓取ip
的網址,當成功抓到的時候我們就回傳response
從訊息上來看,成功回傳了ip
位置,而且status:200
表示資料抓取正常。
那麼接著故意來把網址打錯看一下catch
的結果
由於fetch
找不到「 http://httpbin.org/ipa 」這個網址,因此就噴了catch
,回傳 status:404
,找不到網頁的錯誤訊息。
fetch('http://httpbin.org/post',{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
mode: 'cors',
body: JSON.stringify({message: 'POST資料是否成功'})
})
.then(function(response){
console.log(response);
return response.json();
})
.then(function(data){
console.log(data);
})
.catch(function(err){
console.log(err);
});
接著來用fetch
實作一下POST
的方法,使用「 http://httpbin.org/post 」,並在後面可以傳一個請求的物件內容,接著讓我們POST
一個json
資料格式過去,再看看then
,能不能接收到post
成功的訊息。
console
視窗如願,看到了我們設定的json
訊息,這樣就成功透過fetch
做簡易的POST
請求。
GitHub
上有幾個認可的Promise
及Fetch API
可以使用,當瀏覽器吃不到功能時,可以藉由這些實作特色的library
來代替。
Promise
在官網有提到四種替代函式庫Fetch
以Promise做示範
if(!window.Promise){
window.Promise = Promise;
}
當瀏覽器找不到Promise
的時候,就將函式庫的功能指定給瀏覽器的Promise
。
這樣就能讓某些較舊的瀏覽器也能吃到API
的好處了。
Promise
和Fetch
還有許多細節的學問,但是我想就此打住,避免學習主題的失焦,也怕內容越打越長,因此,今天就先稍微了解API
的基本的使用方式,接下去在讓我們將這個特色發揮到Service Worker
上吧!
請問下,這樣說是否正確呢 ?Service Worker
本身也是條單
執行續,所以依舊有Event Loop
那些觀念在 !