本文原文: 更快的异步功能和promise
JavaScript中的异步处理传统上以速度不快而闻名。更糟的是,调试实时JavaScript应用程序(特别是Node.js服务器)不是一件容易的事情,尤其是在异步编程方面。幸运的是,时代正在改变。本文探讨了如何在V8中优化异步函数和promis(在某种程度上,在其他JavaScript引擎中也是如此),并描述了如何改进异步代码的调试体验。
注意: 如果你更喜欢观看演示文稿而不是阅读文章,那么请欣赏下面的视频!如果不是,请跳过视频并继续阅读。
一种新的异步编程方法
从回调到promis到异步功能
在promises成为JavaScript语言的一部分之前,基于回调的API通常用于异步代码,尤其是在Node.js中。这是一个例子:
function handler(done) {
validateParams(error => {
if (error) return done(error);
dbQuery((error, dbResults) => {
if (error) return done(error);
serviceCall(dbResults, (error, serviceResults) => {
console.log(result);
done(error, serviceResults);
});
});
});
}
以这种方式使用深度嵌套回调的特定模式通常被称为*“回调地狱”* ,因为这会降低代码的可读性并且难以维护。
幸运的是,现在promises已经成为JavaScript语言的一部分,同样的代码可以用更优雅和更易于维护的方式编写:
function handler() {
return validateParams()
.then(dbQuery)
.then(serviceCall)
.then(result => {
console.log(result);
return result;
});
}
最近,JavaScript获得了对异步功能的支持。现在可以用与同步代码非常相似的方式编写上述异步代码:
async function handler() {
await validateParams();
const dbResults = await dbQuery();
const results = await serviceCall(dbResults);
console.log(results);
return results;
}
使用异步函数,代码变得更简洁,控制和数据流也更容易理解,尽管执行仍然是异步的。(注意,JavaScript执行仍然发生在一个线程中,这意味着异步函数最终不会自己创建物理线程。)
从事件侦听器回调到异步迭代
另一个在Node.js中特别常见的异步范例是ReadableStream。这是一个例子:
const http = require("http");
http
.createServer((req, res) => {
let body = "";
req.setEncoding("utf8");
req.on("data", chunk => {
body