JavaScript Asynchronous Code Evolution

随着JavaScript语言的不断发展,ECMAScript标准也随之更新,使得JavaScript成为了一个广泛使用的现代编程语言。在ECMAScript中,异步编程是一个得到极大改进的领域。如果是新开发者,可以在这里学习更多关于异步编程的知识。幸运的是,Windows 10中的新版Edge浏览器已经包含了这些改进——查看Microsoft Edge的更新日志。

在所有这些新特性中,让特别关注“ES2016 Async Functions”,它位于“Experimental Javascript”特性标志后面,将通过更新来了解ECMAScript如何改进当前的工作流程。

第一站:ECMAScript 5 – 回调函数之城

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 –Promises之城

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()等调用。

终点站:ECMAScript7 – 异步之城

最后,到达了目的地!几乎在未来,但感谢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上的编码实验室:跨浏览器测试和最佳实践

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485