随着JavaScript语言的不断发展,ECMAScript标准也随之更新,使得JavaScript成为了一个广泛使用的现代编程语言。在ECMAScript中,异步编程是一个得到极大改进的领域。如果是新开发者,可以在这里学习更多关于异步编程的知识。幸运的是,Windows 10中的新版Edge浏览器已经包含了这些改进——查看Microsoft Edge的更新日志。
在所有这些新特性中,让特别关注“ES2016 Async Functions”,它位于“Experimental Javascript”特性标志后面,将通过更新来了解ECMAScript如何改进当前的工作流程。
ECMAScript 5(以及之前的版本)都是关于回调函数的。为了更好地理解这一点,让举一个每天至少使用一次的简单例子:执行XHR请求。
var displayDiv = document.getElementById("displayDiv");
var processJSON = function (json) {
var result = JSON.parse(json);
result.collection.forEach(function(card) {
var div = document.createElement("div");
div.innerHTML = card.name + " cost is " + card.price;
displayDiv.appendChild(div);
});
};
var displayError = function(error) {
displayDiv.innerHTML = error;
};
var xhr = new XMLHttpRequest();
xhr.open('GET', "cards.json");
xhr.onload = function(){
if(xhr.status === 200) {
processJSON(xhr.response);
}
};
xhr.onerror = function() {
displayError("Unable to load RSS");
};
xhr.send();
有经验的JavaScript开发者会注意到这看起来多么熟悉,因为XHR回调函数经常使用!它简单且相当直接:开发者创建一个XHR请求,然后为指定的XHR对象提供回调函数。
相比之下,回调函数的复杂性来自于执行顺序不是线性的,这是由于异步代码的内在性质:“回调地狱”甚至可能更糟,当在自己的回调函数中使用另一个异步调用时。
ECMAScript 6正在获得动力,Edge浏览器也有领先的支持,目前覆盖率达到88%。在许多伟大的改进中,ECMAScript 6标准化了promises(以前称为futures)的使用。根据MDN,一个promise是一个用于延迟和异步计算的对象。一个promise代表一个尚未完成的操作,但预计将来会完成。Promises是一种组织异步操作的方式,使它们看起来像是同步的。这正是XHR示例所需要的。
Promises已经存在一段时间了,但好消息是现在不需要任何库,因为它们由浏览器提供。
var displayDiv = document.getElementById("displayDiv");
function getJsonAsync(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => {
if(xhr.status === 200) {
resolve(xhr.response);
} else {
reject("Unable to load RSS");
}
};
xhr.onerror = () => {
reject("Unable to load RSS");
};
xhr.send();
});
};
getJsonAsync("cards.json").then(json => {
var result = JSON.parse(json);
result.collection.forEach(card => {
var div = document.createElement("div");
div.innerHTML = `${card.name} cost is ${card.price}`;
displayDiv.appendChild(div);
});
}).catch(error => {
displayDiv.innerHTML = error;
});
可能已经注意到了很多改进。让仔细看看。
创建promise 为了“promisify”(抱歉,是法国人,所以被允许发明新词)旧的XHR对象,需要创建一个Promise对象:
使用promise 一旦创建,promise就可以用于以更优雅的方式链式调用异步调用:
所以现在有(从用户的角度来看): 获取promise (1) 链式调用成功代码 (2和3) 链式调用错误代码 (4) 就像在try/catch块中一样
有趣的是,链式调用promise可以很容易地使用.then().then()等调用。
最后,到达了目的地!几乎在未来,但感谢Edge的快速发展周期,团队能够在最新版本中引入一些ECMAScript 7的async functions!
Async functions是改进异步代码编写的语言级模型的语法糖。Async functions是建立在ECMAScript 6特性(如generators)之上的。实际上,可以使用generators与promises联合使用,以产生相同的结果,但用户代码更多。
不需要改变生成promise的函数,因为async functions直接与promise一起工作。
只需要改变调用函数:
(async function() {
try {
var json = await getJsonAsync("cards.json");
var result = JSON.parse(json);
result.collection.forEach(card => {
var div = document.createElement("div");
div.innerHTML = `${card.name} cost is ${card.price}`;
displayDiv.appendChild(div);
});
} catch(e) {
displayDiv.innerHTML = e;
}
})();
这就是魔法发生的地方。这段代码看起来像是一个普通的同步代码,具有完美的线性执行路径:
相当令人印象深刻,对吧?
好消息是,甚至可以在箭头函数或类方法中使用async functions。
如果想了解在Chakra中是如何实现的,请查看Microsoft Edge博客上的。也可以使用Kangax的网站跟踪各种浏览器实现ECMAScript 6和7的进展。
欢迎查看!请随时给反馈,并通过使用投票按钮支持最喜欢的特性:
感谢阅读,渴望听到反馈和想法!
这篇文章是微软技术传道者和工程师关于实用的JavaScript学习、开源项目和互操作性最佳实践的Web开发系列文章的一部分,包括Microsoft Edge浏览器和新的EdgeHTML渲染引擎。
鼓励在包括Microsoft Edge在内的浏览器和设备上进行测试——Windows 10的默认浏览器——在dev.modern.IE上有免费的工具:
扫描网站,查找过时的库、布局问题和可访问性问题 为Mac、Linux和Windows使用虚拟机 远程测试自己的设备上的Microsoft Edge GitHub上的编码实验室:跨浏览器测试和最佳实践