在前面文章中,分别说了脚步语言程序中用原生方式和Promise对象实现异步操作,通过上面两篇文章说明可以看出用Promise对象方法更简单。想了解脚步原生方式实现异步操作,请点击 这里 进入查看;而想了解Promise对象实行异步操作,请点击 这里 进入查看;此外,还继续说了Promise对象的then链用法,请点击 这里 进入查看。
除了原生方式和Promise的then链方式,Javascript等脚步语言还定义了一组函数,即async和await函数,来实现异步操作的。相信大家至此会不会有点奇怪,不是有了Promise的then链,为啥还要async和await函数来实现异步操作,是不是多余啦,有关两者之间的区别与联系将会在后续文章陈述,尽请期待。
回到正题,本文主要讲述async和await函数是如何实现异步操作的。async 是“异步”英文单词的缩写,而 await 可认为是 async wait 的简写,故此理解 async就是申明异步函数的,而 await 用于等待一个异步函数方法执行完成。
一、async函数
先来看看一个async函数例子,代码如下:
async function runAsync(name) {
return "runAsync to "+name;
}
const aResult = runAsync('MaShu');
console.log(aResult);
console.log("runAsync called");
结果输出:
Promise { <state>: "fulfilled", <value>: "runAsync to MaShu" }
runAsync called
从上面输出来看,异步函数runAsync
实际上返回了一个Promise对象,而且执行完成之后Promise的状态是fulfilled
。其实,相当于函数返回语句等价于Promise的即刻成功答复,代码如下:
Promise.resolve('runAsync to MaShu');
如此看来,我们可以把异步函数改造为普通函数,功能是一样的,代码如下:
function runAsync(name) {
return new Promise(resolve => {
resolve("runAsync to "+name);
});
}
const aResult = runAsync('MaShu');
console.log(aResult);
console.log("runAsync called");
这个普通函数执行结果跟上面的异步函数输出结果是一样的,不过异步函数方式的写法变得简单了。大家不禁会问,除了写法简单之外,还有其他作用吗?回答这个问题之前,咱们不妨继续看代码实例,代码如下:
function runAsync(name) {
return new Promise(resolve => {
setTimeout(() => resolve("runAsync to "+name), 2000);
});
}
function callAsync() {
console.log("called begin");
const aResult = runAsync('MaShu');
console.log(aResult.then((val)=>{console.log(val)}));
console.log("called end");
}
callAsync();
注释:runAsync
函数没有在前面添加关键字“async”来定义异步函数,因为它的许诺返回是即刻成功答复,而没有模拟异步执行场景的,故改为等价方式表达,即返回显示构建的许诺Promise对象,对象成功答复延迟2秒。
上述代码执行结果,如下:
called begin
Promise { <state>: "pending" }
called end
runAsync to MaShu
从上面结果来看,延迟2秒成功答复场景模拟并发现,异步函数runAsync
是异步执行的。
如果想等待函数runAsync
执行完成之后,调用函数才继续执行,是否可以做到吗?答案是肯定的,这就得依靠await函数啦。
二、await函数
继续上面的代码示例,稍做代码修改,如下:
function runAsync(name) {
return new Promise(resolve => {
setTimeout(() => resolve("runAsync to "+name), 2000);
});
}
async function callAsync() {
console.log("called begin");
const aResult = await runAsync('MaShu');
console.log(aResult);
console.log("called end");
}
callAsync();
这时代码执行结果,如下:
called begin
runAsync to MaShu
called end
从上面输出结果可以看出,原本是异步执行的代码被强制阻塞等待完成之后,才继续后续代码。这相当于做到了“异步执行被改为同步执行”的效果。
特别提示一下,await
必须要在async
函数里执行,否则有错误提示。
总而言之,async
函数其实就是Promise对象实现异步操作的一种简洁写法而已,而await
是为了实现某些时候需对异步操作做阻塞等待完成的意图而设计的,这样异步与同步组合起来比较灵活,能更好地满足不同的功能需求场景的真实需要。
原文来自码嗨路书