异步的概念:
简单说异步就是一个任务是不连续执行的,先执行第一段,然后转而执行其他任务,等做好了准备再执行第二段。比如有一个任务是读取文件进行处理,该任务的第一段是向操作系统发送请求,要求读取文件,为了保证cpu的利用率,计算机会执行其他任务等到操作系统返回文件再转而继续执行下一段。相应的,连续的执行叫同步,由于是连续执行,不能插入其他任务,所以操作系统从硬盘读取文件的这段时间,程序只能干等着。
回调函数:
JavaScript对异步编程的实现,就是回调函数。所谓回调函数,就是把任务的第二段单独写在一个函数里面,等重新执行这个任务的时候,就直接调用这个函数,回调函数的英文名字'callback',就是重新调用的意思。
async函数是Generator生成器语法糖,相比Generator其有如下改进之处:
(1)内置执行器
Generator函数必须依靠执行器,而async函数自带执行器,也就是说async函数的执行与普通函数一模一样,只要一行。
(2)更好的语义
async函数的await,比起星号和yield,语义更清楚了,async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
(3)更广的适用性
async函数的await命令后面,可以是promise对象和原始类型的值(数值、字符串、布尔值),原始类型的值这时会自动转成立即resolved的promise对象。
(4)返回值是Promise对象
async函数的返回值是Promise对象,比Generator函数返回iterator对象方便多了,可以用then方法指定下一步的操作
async函数的语法:
1.async函数的返回值
async函数返回一个Promise对象,
async函数内部的return语句返回的值会成为then方法的参数。
2.Promise对象的状态变化
async函数的状态变化必须等到内部所有await命令后面的promise对象执行完,才会发生状态改变,除非遇到return语句或抛出错误,也就是说只有async内部的所有异步操作执行完,才会执行then方法指定的回调函数。
3.await命令
正常情况下await命令后面是一个promise对象,返回该对象的结果,如果不是promise,就直接返回对应的值
示例代码1:
async function fn(){
await setTimeout(()=>{console.log('12'),2000})
console.log('we')
}
fn()
定时器执行=>打印‘we’=>定时器执行完成
示例代码2(加了async标志的函数的返回值都是一个Promise对象):
async function fn(){
await setTimeout(() => {
console.log('hello')
}, 3000);
}
console.log(fn())//Promise
示例代码3:
async函数返回一个Promise对象;
async函数内部的return语句返回的值会成为then方法的参数;
抛出错误会导致promise对象的状态变为rejected,抛出的错误对象会被catch回调函数接收到。
async function fn(){
// throw new Error('oh!')
return 'yamy'
}
fn()
.then((value)=>console.log('sucess'+value))
.catch((err)=>console.log(err))
示例代码4:
async函数返回一个promise对象,可以使用then方法添加回调函数,当函数执行的时候一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体后面的语句。
function timeout(ms){
return new Promise((res,rej)=>{
setTimeout(res,ms)
})
}
async function print(value,ms){
await timeout(ms)
console.log(value)
}
print('hello world',3000)
async函数会首先输出一个promise对象,然后会监听await后面promise对象的返回状态,当这状态为resolved的时候再往下执行其他代码。
示例代码5:
async function timeout(ms){
await new Promise((res)=>{
setTimeout(res,ms)
})
}
async function print(value,ms) {
await timeout(ms)
console.log(value)
}
print('hello',3000)
会有两次等待状态,第一次等待定时器执行完成,第二次等待timeout函数执行完成。
示例代码6:每个await命名运行完后函数再return
async function get(){
await console.log('hello')
await new Promise((res,rej)=>{
setTimeout(() => {
console.log('world')
res('sucess')
}, 3000)
})
return 'mariner'
}
get().then((val)=>console.log(val))
.catch((err)=>console.log(err))
示例代码7:
async function fn1(){
let w=await new Promise((res,rej)=>{//返回值是hello
setTimeout(()=>res('hello',2000))
})
return w
}
fn1().then((val)=>{console.log(val)})//hello