ES8(ECMAScript 2017)新增了 async
、await
語法,如〈Promise〉中談過的,可以用來令非同步的流程,不用是透過回呼函式,而像是循序撰寫的語法。
Fetch API 有許多方法,都是傳回 Promise
,因此搭配 async
、await
語法,可以令程式更為簡潔,例如〈簡介 Fetch API〉中的第一個範例,可以改寫為:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<button id='req'>取得表格</button>
<div id="table"></div>
<script type="text/javascript">
document.getElementById('req').onclick = async function() {
let resp = await fetch('XMLHttpRequest-1.txt');
let text = await resp.text();
document.getElementById('table').innerHTML = text;
};
</script>
</body>
</html>
await
可以承接傳回 Promise
的 API,直到有結果之後,流程才會往下一步,await
只能撰寫在 async
標示的函式之中,然而,事件處理器可以標示為 async
,這使得程式撰寫起來簡單許多。
來將〈簡介 Fetch API〉中第二個範例改寫為 async
、await
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
新增書籤:<br>
網址:<input id="url" type="text">
<span id="message" style="color:red"></span><br>
名稱:<input type="text">
<script type="text/javascript">
function params(paraObj) {
return Object.keys(paraObj)
.map(name => {
let paraName = encodeURIComponent(name);
let paraValue = encodeURIComponent(paraObj[name]);
return `${paraName}=${paraValue}`.replace(/%20/g, '+');
})
.join('&');
}
document.getElementById('url').onblur = async function() {
let reqString = params({
url : document.getElementById('url').value
});
let resp = await fetch('POST-1.php', {
method : 'POST',
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
body : reqString
});
let text = await resp.text();
if(text === 'existed') {
document.getElementById('message').innerHTML = 'URL 已存在';
}
};
</script>
</body>
</html>
底下則是將〈簡介 Fetch API〉中最後一個範例改寫為 async
、await
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<body>
ID:<input id="id">
<button id="test">JSONP 測試</button>
<span id="result"></span>
</body>
<script type="text/javascript">
document.getElementById('test').onclick = async function() {
let id = document.getElementById('id').value;
let result = document.getElementById('result');
let resp = await fetch(`https://openhome.cc/Gossip/ECMAScript/samples/CORS-1.php?id=${id}`, {
mode : 'cors'
});
let person = await resp.json();
result.innerHTML = `${person.name}, ${person.age}`;
};
</script>
</body>
</html>
當然,Promise
是一種流暢風格,而 async
、await
是另一種風格,就看各自偏好哪個了。