async函数

211 阅读3分钟

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方法, 处理前面可能出现的错误.

  1. 使用注意点 (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) }) }) } 其他问题