async函数
async函数是什么?
他就是Generator函数的语法糖
async函数就是将grnerator函数的(*) 替换成async ,将 yield替换成 await
改进
(1)内置执行器
Generator 函数执行必须依靠执行器, 而async函数自带执行器. 也就是说 async函数的执行与普通函数一模一样, 只要一行
//async 函数自动执行
const asyncReadFile = async function(){
await console.log('hello')
await console.log('world')
}
//如果使用Generator函数需要next方法才能真正执行
//生成器对象
function* get(){
yield console.log('hello')
yield console.log('world')
}
let g = get()
g.next() // 'hello'
g.next() // 'world'
// 升级
async function get(){
await setTimeout(()=>{
console.log('hello')
},2000) // 两秒后执行 输出hello
await console.log('world')
}
(2)改进之处
async和await , 比起星号和yield , 语义就更加清楚 , async表示函数里有异步操作, await表示紧跟在后面的表达式需要等待结果
async function get(){
await new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('hello')
resolve('李大庆')
})
})
await console.log('world')
}
(3)更广的是适用性
async函数的await命令后面, 可以是Promise 对象和原始类型的值 (数值、字符串和布尔值, 但这是会自动转成立即resolved 的 Promise 对象 )
(4)返回值是Promise
async 函数的返回值是 Promise 对象,这比Generator 函数的返回值是 Iterator 对象航标多了 . 你可以用 then 方法指定下一步的操作
axync 函数的语法应用
axync函数的语法简单, 难点是错误处理机制
1.async 函数的返回值
async函数返回以恶 Promise 对象
async 函数内部 return 语句返回的值, 会成为 then 方法回调函数的参数
async function f(){
return 'hello woeld';
}
f().then(v => console.log(v))
//上面代码函数f内部1return 命令返回的值, 会被then 方法回调函数接收到
//async函数内部跑哦出错误, 会导致返回的Promise 对象变为reject状态. 抛出的错误对象会被catch方法回调函数接收到
3.await命令
async function f(){
await Promise.reject('出错了')
}
f()
.then(v => console.log(v))
.catch(e =. console.log(e))
// await 命令后面的Promise对象如果变为reject状态, 则reject的参数会被catch方法的回调函数接收到
async function f(){
await Promise.reject('出错了')
await Promise.resolve('hello world')//不会执行
}
// 上面代码中, 第二个await语句是不会执行的, 因为第一个await语句状态变成了reject
(1) 有时我们希望即使前一个异步操作失败, 也不要中高端后面的异步操作做. 这是可以加功第一个await放在 try...catch 结构里面, 则按不管这个异步是否成功, 第二个都会执行
(2) 另一种方法是await 后面的Promise 对象再跟一个catch方法, 处理前面可能出现的错误.
4. 使用注意点
(1) await 命令后面的Promise对象, 运行结果可能是rejected, 所以最好把await命令放置在try ... catch代码块中
async function myFunction(){
try{
await something()
}catch(err){
console.log(err)
}
}
//另一种写法 最好这么写
async function myFunction(){
await something().catch(function (err){
console.og(err)
})
}
(2) 多个await命令后面的异步操作, 如果不存在继发关系, 最好让他们同时触发
let foo = await getFoo()
let bar = await getBar()
//getFoo和getbar 是两个独立的异步操作(即互不依赖) ,被下腭侧给计划关系 这样比较耗时, 因为之哟个体Foo完成以后, 才会执行getbar, 完全而已让他们同时触发
//写法一
let [foo,
bar] = await Promise
.all([
getFoo(),
getBar()
])
//写法二
let footPromise = getFoo()
let barPromise = getBar()
let foo = await fooPromise
let bar = await barPromise
//上面两中写法, getFoo和getBar的都是同时触发, 这样就会缩短程序的执行时间
async 函数的实现原理
//async 函数的实现原理,就是将Generator 函数和自执行器, 包装在一个函数里
async function fn(args){
// ...
}
//等同于
function fn(args){
return spawn(function* (){
// ...
})
}
//所有的async函数都可以直接写成上面的第二种形式, 其中spawn函数就是自执行器
//原理
function spawn(genF){
return new Promise(function (resolve,reject){
const gen = genF()
function step(nextF){
let next
try{
next = nextF()
}catch(e){
return reject(e)
}
if(next.done){
return resolve(next.value)
}
Promise.resolve(next.value).then(function(v){
step(function(){ return gen.next(v) })
}, function(e){
step(function(){ return gen.throw(e) })
})
}
step(function(){ return gen.next(undefind) })
})
}
其他问题