async和await让异步编程更简单

这是场接力赛,你却当成百米赛跑。

async

首先,我们使用async关键字,您可以将它放在函数声明之前,将其转换为async function。异步函数是一个知道怎样预期 await 关键字可用于调用异步代码可能性的函数。

尝试在浏览器的JS控制台中键入以下行:

1
2
function hello() { return "Hello" };
hello();

该函数返回“Hello” ––没什么特别的,对吧?

但是,如果我们将其变成异步函数呢?请尝试以下方法:

1
2
async function hello() { return "Hello" };
hello();

额。。现在调用该函数会返回一个promise。这是异步函数的特征之一 ––它将任何函数转换为promise。
你也可以创建一个异步函数表达式(参见async function expression),如下所示:

1
2
let hello = async function() { return "Hello" };
hello();

你可以使用箭头函数:

1
let hello = async () => { return "Hello" };

这些都基本上是一样的。

要实际使用promise实现时返回的值,因为它返回了一个promise,我们可以使用.then()块:

1
hello().then((value) => console.log(value))

甚至只是简写如

1
hello().then(console.log)

就像我们在上一篇文章中看到的那样
因此,将async关键字添加到函数中以告诉它们返回promise而不是直接返回值。此外,这使同步函数可以避免运行支持使用await时带来的任何潜在开销。通过仅在函数声明为异步时添加必要的处理,JavaScript引擎可以为您优化您的程序。爽!

await

将它与await关键字结合使用时,异步函数的真正优势就变得明显了。这可以放在任何基于异步声明的函数之前,暂停代码在该行上,直到promise完成,然后返回结果值。与此同时,其他正在等待执行机会的代码就有可能如愿执行了。
这是一个简单的示例:

1
2
3
4
5
async function hello() {
return greeting = await Promise.resolve("Hello");
};

hello().then(alert);

关键字 await 让 JavaScript 引擎等待直到 promise 完成(settle)并返回结果
这里的例子就是一个 1 秒后 resolve 的 promise:

1
2
3
4
5
6
7
8
9
10
11
12
async function f() {

let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});

let result = await promise; // 等待,直到 promise resolve (*)

alert(result); // "done!"
}

f();

这个函数在执行的时候,“暂停”在了 (*) 那一行,并在 promise settle 时,拿到 result 作为结果继续往下执行。所以上面这段代码在一秒后显示 “done!”

让我们强调一下:await 字面的意思就是让 JavaScript 引擎等待直到 promise settle,然后以 promise 的结果继续执行。这个行为不会耗费任何 CPU 资源,因为引擎可以同时处理其他任务:执行其他脚本,处理事件等。

相比于 promise.then,它只是获取 promise 的结果的一个更优雅的语法,同时也更易于读写。