asyncawait的基础使⽤及原理简介
async/await是es7推出的⼀套关于异步的终极解决⽅案,为什么要说他是终极解决⽅案呢?因为他实在是太好⽤了,⽽且写起来还⾮常的简单。
⼀:async/await基础语法
// 定义⼀个异步函数(假设他是⼀个异步函数)
getJSON(){
return 'JSON'
}
// 在需要使⽤上⾯异步函数的函数前⾯,加上async声明,声明这是⼀个异步函数
async testAsync() {
// 在异步函数前⾯加上await,函数执⾏就会等待⽤await声明的异步函数执⾏完毕之后,在往下执⾏
await getJSON()
...剩下的代码
}
以上就是async/await最基本的⽤法。
还需要注意的⼀点就是使⽤async/await的时候,是⽆法捕获错误的,这个时候就要⽤到我们es5⾥⾯⼀个被⼤家遗忘了的try/catch,来进⾏错误的捕获:
async testAsync() {
try {
await getJSON()
} catch(err) {
console.log(err)
}
...剩下的代码
}
注意:
1.async函数在声明形式上和普通函数没有区别,函数声明式,函数表达式,对象⽅法,class⽅法和箭头函数等都可以声明async函数。
2.任何⼀个await语句后⾯的 Promise 对象变为reject状态,那么整个async函数都会中断执⾏。
3.async函数返回的 Promise 对象,必须等到内部所有await命令后⾯的 Promise 对象执⾏完,才会发⽣状态改变,除⾮遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执⾏完,才会执⾏then⽅法指定的回调函数。
⼆:async/await
async
async这个单词⼤家应该都⽐较熟悉,他是英⽂单词‘异步’的简写,代表的意思也是异步。
async function testAsync() {
return "hello async";
}
const result = testAsync();
console.log(result);
输出结果:
Promise{<resolved>: "hello async"}
可以看出async函数,返回的是⼀个Promise对象
await
await是英⽂单词‘等待’的意思,代表的意思也是等待,那他等的到底是个什么东西呢?还是⼀个Promise。
三 async/await和Generator
Generator函数:generator(⽣成器)是ES6标准引⼊的新的数据类型。⼀个generator看上去像⼀个函数,但可以返回多次。下⾯⾯是⼀个Generator函数的简单写法。
function* Generator() {
yield '11111111';
yield '22222222'
return '3333333';
}
let aaa = Generator();
Generator函数和普通函数⼀样通过函数名+()去调⽤,但是调⽤完之后并不执⾏。它仅仅是创建了⼀个generator对象,还没有去执⾏它。想要运⾏Generator函数,需要通过遍历器对象的next⽅法。
let a = ()
let b = ()
let c = ()
let d = ()
console.log(a,b,c,d) //  {value: "11111111", done: false}    {value: "22222222", done: false}      {value: "3333333", done: true}    {value: undefined, done: true}
想要Generator函数执⾏下⼀步,必须调⽤遍历器对象的next⽅法,使得指针移向下⼀个状态。也就是说,每次调⽤next⽅法,内部指针就从函数头部或上⼀次停下来的地⽅开始执⾏,直到遇到下⼀个yield表达式或return语句。由此可见,Generator 函数是分段执⾏的,yield表达式是暂停执⾏的标记,⽽next⽅法可以恢复执⾏。也就是上⾯说的可以交出函数的执⾏权。
上⾯对Generator函数做了⼀个简单的介绍,接下来说⼀下async/await和Generator。
根据阮⼀峰⽼师的介绍,async函数就是Generator函数的语法糖。
图⽚:
代码上看起来,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await。
实际上async函数对Generator函数的改进,体现在⼀下四点:
1.async函数⾃带执⾏器,所以执⾏⽅式和普通函数的执⾏⽅式⼀样,通过函数名+()的⽅式执⾏。
2.async和await⽐起*和yield在语义上更清楚。
<模块约定,yield命令后⾯只能是 Thunk 函数或 Promise 对象,⽽async函数的await命令后⾯,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会⾃动转成⽴即 resolved 的 Promise 对象)。
4.async函数的返回值是 Promise 对象,这⽐ Generator 函数的返回值是 Iterator 对象⽅便多了。你可以⽤then⽅法指定下⼀步的操作。
进⼀步说,async函数完全可以看作多个异步操作,包装成的⼀个 Promise 对象,⽽await命令就是内部then命令的语法糖。
四:async/await和Promise
上⾯说了async/await和Generator的关系,这⾥再说⼀下和Promise的关系,async/await其实是基于Promise的。async函数其实是把Promise包装了⼀下。
下⾯是⼀个async/await的写法:
getConstant() {
return 1
}
async getAsyncConstant() {
return 1
}
async getPromise() {
return new Promise((resolved, rejected)=> {
resolved(1)
});
}
async test() {
let a = 2
let c = 1
await getConstant();
let d = 3
await getPromise();
let d = 4
await getAsyncConstant();
return 2
}
上⾯的代码其实真正的在解析执⾏的时候是这样的:
function getConstant() {
return 1;
}
function getAsyncConstant() {
solve().then(function () {
return 1;
});
}
function getPromise() {
solve().then(function () {
return new Promise((resolved, rejected) => {
resolved(1);
});
});
}
test() {
solve().then(function () {
let a = 2;
let c = 1;
return getConstant();
}).then(function () {
let d = 3;
return getPromise();
}).then(function () {
let d = 4;
return getAsyncConstant();
}).then(function () {
return 2;
});
}
通过上⾯的代码可以看出async/await的本⾝还是基于Promise的。
因为await本⾝返回的也是⼀个Promise,它只是把await后⾯的代码放到了await返回的Promise的.then后⾯,以此来实现的。做个练习:
function getJson(){
return new Promise((reslove,reject) => {
setTimeout(function(){
console.log(2)
reslove(2)
},2000)
})
}
async function testAsync() {
await getJson()
console.log(3)
}
testAsync()
上⾯的代码是会先打印2还是3?
答案是2,3
看过上⾯的童鞋应该知道其实他的真实代码是这样的:
function getJson(){
return new Promise((reslove,reject) => {
setTimeout(function(){
console.log(2)
reslove()
},2000)
})
}
function testAsync() {
await和async使用方法
return new Promise((reslove,reject) => {
getJson().then(function (res) {
console.log(3)
})
})
}
testAsync()

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。