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
是另一种风格,就看各自偏好哪个了。