1、async
async使用在函数前面,把函数变成一个异步函数,返回值是个promise对象。
1、返回一个数值
async function asy (str) {
return str;
}
console.log(asy('sadasdasds')) //Promise { 'sadasdasds' }
直接返回一个数值会得到一个promise,可以在调用asy('sadasdasds')后面跟上then就可以直接得到传进去的数值了。
2、返回一个promoise对象
async function asy (str) {
const pro = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(str);
},1000)
})
return pro;
}
console.log(
asy('sadasdasds').then(res =>{
console.log(res);
})
)
//结果
//Promise { <pending> }
//sadasdasds
和返回数值是一样的,返回的是一个promise。
2、await
await只能使用在async声明的函数里,不能使用在普通函数里。
function errAsy () {
await new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('errAsy!')
},1000)
})
}
errAsy() //SyntaxError: await is only valid in async function
直接使用在普通函数里,直接报错SyntaxError: await is only valid in async function。
await的作用:
async function asy (str) {
const str1 = await new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(str);
console.log('step1')
},1000)
})
console.log('step2: '+str1);
return str1 ;
}
asy('sadasdasds').then(res => {
console.log('step3: '+res);
})
//输出结果
//step1
//step2: sadasdasds
//step3: sadasdasds
在上面代码中,asy里面new了一个promise,按理异步操作来说,会先输出'step2: '+str1,但是由于await的作用下,把promise这个异步阻塞了,导致执行结果是等待1s后,先输出延时定时器里的step1并把str返回给str1,然后才开始执行输出下面的step2,最后return str1。asy return的str1被当作一个promise返回,使用then就可以获取到str1。这最后一步操作和最前面第一种返回数值的操作结果是一致的。所以await在async中有起到把异步变成同步的作用并且把resolve里的结果返回。
3、async最大的作用
假设有一件事情需要分三个步骤完成,这三个步骤全部做完需要多少时间呢?
我们用一个函数代表这个一个步骤所花的时间,那么三个步骤依次完成就是这个事件完成一共所花的时间了。函数代码:
function takeTimes (ms) {
return new Promise((resolve)=>{
setTimeout(()=>{
resolve(ms);
}, ms)
})
}
ms为当前步骤所花的时间,当这个步骤花完后返回所花费时间。所以第一个步骤所花的时间就是
takeTimes(1000).then((res)=>{
console.log(res);
})
第二个步骤所花时间为
takeTimes(1000).then((res)=>{
console.log(res);
takeTimes(1000).then((res1)=>{
console.log(res1);
})
})
第三次步骤所花的时间为
takeTimes(1000).then((res)=>{
console.log(res);
takeTimes(1000).then((res1)=>{
console.log(res1);
takeTimes(1000).then((res2)=>{
console.log(res1+res1+res2)
})
})
})
在第三次步骤完成后就代表这个事件完成了,所以res+res1+res2就是这个事件完成最终花费的时间。
上面也就才3个步骤,如果一个事件需要更多的步骤去完成呢?无线嵌套的噩梦无法想象。那么来看看async去实现上面的这个事件是怎么操作的呢?
我们保留一个步骤所花的时间的函数:
function takeTimes (ms) {
return new Promise((resolve)=>{
setTimeout(()=>{
resolve(ms);
}, ms)
})
}
那么三次所花费的时间:
async function asy () {
const ms = await takeTimes(1000);
const ms1 = await takeTimes(1000);
const ms2 = await takeTimes(1000);
console.log(ms+ms1+ms2);
}
asy(); //3000
上面代码中,我们使用await去阻塞takeTimes,让他执行完当前步骤后然后这个步骤所花的时间,然后依次执行第二第三次步骤,最后把累计花费的时间累加就是这个事件所花的时间了,是不是比promise的回调嵌套简洁多了呢?
上面那个只是一个事件分步骤所花的时间,我们把这个事件结合我们项目里去思考。假设我们一个网页需要依赖用户上一个操作的结果去执行下一个请求数据呢?是不是也可以只用呢?
笔者由于知识问题,如果有哪些说的有问题,请别见怪。更多async的知识详见https://segmentfault.com/a/1190000007535316这个大佬的文章,我这里只是写下自己的个人理解。