async作为关键字放在函数名前面,表示该函数是个异步函数。
async function testAsync(){
console.log(‘async’)
}
async函数返回的是一个promise对象。即testAsync()返回的是promise对象,如果要获取到函数内部的输出或返回值,那么需要用到then方法,即:
testAsync().then(result=>{
conosle.log(result);
})
await
await 用法 注意: 只能出现在async声明的函数中
变量=await expression(promise对象)
await等到的若是promise对象,那么await语句会阻塞后面的语句的执行,在等待resolve的值后,将其作为表达式的运算结果返回给await。
async function testAsync() {
var dataResult = await new Promise(resolve=> {
setTimeout(() => {
resolve('testResult');
console.log('result');
},1000);
});
console.log('test1');
}
输出的结果为:result test1
即遇到await,先等待,等获取到promise的结果后,再执行输出test1;若是没有await语句只有setTimeout,则输出顺序为test1,result。
例: 代码1中的输出结果是 test end,对其进行分析,test函数内返回了一个promise对象,console.log语句会先等待await取值后再往后执行。
代码2中,await置于async函数内部,所以阻塞的是async函数内部await语句后面的语句,外部调用async函数后的执行语句不会被阻塞,所以打印结果是end test。
//代码1
function test() {
return new Promise(resolve => {
setTimeout(() => resolve("test"), 2000);
});
}
const result = await test(); //会对后面的执行语句有阻塞
console.log(result); //等待前面的先执行
console.log('end')
//代码2
function test() {
return new Promise(resolve => {
setTimeout(() => resolve("test"), 2000);
});
}
async function test2() {
const result = await test();
console.log(result);
}
test2();
console.log('end'); //这条语句不会被阻塞,先打印出来
总结:await的使用是会阻塞代码的运行的,所以为了防止这一点,最好将await放于async函数内部,当在外部调用async函数时,对于函数后面的语句的执行不会有阻塞作用
含有async/await的事件执行顺序事例1:
function testSometing() {
console.log("执行testSometing");
return "testSometing";
}
async function testAsync() {
console.log("执行testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
const v1 = await testSometing();//关键点1
console.log(v1);
const v2 = await testAsync();
console.log(v2);
// console.log(v1, v2);
}
test();
执行结果如下:
test start....
执行testsomething
testsomething
执行testAsync
hello async
参考:https://blog.csdn.net/wulex/article/details/80713499
含有async/await的事件执行顺序事例2:
async function test1() {
console.log('start test1');
console.log(await test2());
console.log('end test1');
}
async function test2() {
console.log('test2');
return 'return test2 value'
}
test1();
console.log('start async');
setTimeout(() => {
console.log('setTimeout');
}, 0);
new Promise((resolve, reject) => {
console.log('promise1');
resolve();
}).then(() => {
console.log('promise2');
});
console.log('end async');
代码执行完的顺序分析如下:
1.test1调用,打印出start test1;
2.然后往后执行遇到await test2(),进入到test2方法,打印输出test2;这时停止await后面的语句执行。
3.执行test1(),后面的console.log(start async)同步语句;
4.遇到settimeout(),将其置于事件队列的宏队列中。往后执行。
5.遇到new promise(),先执行console.log(‘’promise1‘’)。然后遇到then语句,将其放于事件队列的微任务队列中。继续往后执行。
6.console.log(‘end async’);
7.此时test1()同步的代码都执行完毕。再次回到test1()中,此时console.log(await test2())执行后返回一个promise对象,将该对象放于微任务队列中。
8.下一步开始执行微任务队列,微任务队列遵循先进先出,所以打印的是then方法中的promise2。
9.然后接着执行微任务队列的test1()中返回的promise对象即‘return test2 value’。
10.await test2()彻底执行完毕,不再阻塞后面的语句,所以接着输出 end test1。
11.微任务队列执行完毕,执行宏任务队列的settimeout,输出settimeout。
12.结束。