美文网首页
async和await

async和await

作者: 小小的白菜 | 来源:发表于2018-10-02 20:54 被阅读0次

浅谈Async/Await
用 async/await 来处理异步

async和await

async:声明一个异步函数(async function someName(){...})

  • 自动将常规函数转换成Promise,返回值也是一个Promise对象;
  • 只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数;
  • 异步函数内部可以使用await

await:暂停异步的功能执行(var result = await someAsyncCall())

  • 放置在Promise调用之前,await强制其他代码等待,直到Promise完成并返回结果;
  • 只能与Promise一起使用,不适用与回调一起使用;
  • 只能在async函数内部使用。
await 容错
  • await的后面需要是一个Promise对象,如果不是则会被转成Promise对象;
  • 只要其中一个如果Promise对象变为reject状态,那么整个async函数都会中断操作;
  • 如果状态是resolve,那么返回值则会变成then里面的参数。
async  function f() {
    return await 123
}
f().then(v => { 
    console.log(v) // 123
})

怎样容错呢?由于await后面的promise运行结果可能是rejected,最好把await放入try {} catch {}中。

await后的异步操作,如果彼此没有依赖关系最好同时触发,在下面场景一会有介绍。

await只能在async函数之中,如果在普通函数中,会报错。

async、await 优缺点
  • asyncawait相比直接使用 Promise来说,优势在于处理then的调用链,能够更清晰准确的写出代码;
  • 缺点在于滥用await可能会导致性能问题,因为 await会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性。
var a = 0
var b = async () => {
  a = a + await 10
  console.log('2', a) // -> '2' 10
  a = (await 10) + a
  console.log('3', a) // -> '3' 20
}
b()
a++
console.log('1', a) // -> '1' 1
  • 首先函数b先执行,在执行到 await 10之前变量a 还是0,因为在await 内部实现了 generatorsgenerators 会保留堆栈中东西,所以这时候a = 0被保存了下来;
  • 因为await 是异步操作,遇到await就会立即返回一个pending状态的Promise对象,暂时返回执行代码的控制权,使得函数外的代码得以继续执行,所以会先执行console.log('1', a)
  • 这时候同步代码执行完毕,开始执行异步代码,将保存下来的值拿出来使用,这时候a = 10
  • 然后后面就是常规执行代码了。
场景一

写一个函数,让它返回promise对象,该函数的作用是2s之后让数值乘以2

// 2s 之后返回双倍的值
function doubleAfter2seconds(num) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(2 * num)
        }, 2000)
    } )
}

现在再写一个async函数,从而可以使用await关键字,await后面放置的就是返回promise对象的一个表达式,所以它后面可以写上 doubleAfter2seconds 函数的调用。

async function testResult() {
    let result = await doubleAfter2seconds(30)
    console.log(result)
}
testResult() // 打开控制台,2s 之后,输出了60.

具体到 我们的代码, 遇到await之后,代码就暂停执行了, 等待doubleAfter2seconds(30)执行完毕,doubleAfter2seconds(30)返回的promise开始执行,2 秒之后,promise执行resolve 了, 并返回了值为60, 这时await才拿到返回值60, 然后赋值给result, 暂停结束,代码才开始继续执行,执行console.log语句。

场景二

我们同时发出三个不互相依赖的请求,如果用async/await就显得不明智了。

async function getABC() {
  let a = await getA() {}
  let b = await getB() {}
  let c = await getC() {}
  return A*B*C
}

上面我们 A 需要 2s,B 需要 4s,C 需要 3s,我们如上图所示发请求,就存在彼此依赖的关系,c 等 b 执行完,b 等 a 执行完,从开始到结束需要(2+3+4)= 9s。
此时我们需要用Promise.all()将异步调用并行执行,而不是一个接一个执行,如下所示:

async function getABC() {
  let results = await Promise.all([ getValueA, getValueB, getValueC])
  return results.reduce((total, value) => total * value)
}

这样将会节省我们不少的时间,从原来的的 9s 缩减到 4s,是不是很开心,耶~

相关文章

  • async和await

    浅谈Async/Await用 async/await 来处理异步 async和await async:声明一个异步...

  • ES8(一) —— async&await

    目录 async和普通函数的区别 await async/await处理多回调异步 async和await必须配合...

  • ES6中的好东西

    1 Await/Async 前端的回调时代我没有赶上,我赶上的是await/async时代。await和async...

  • 使用 async 和 await,实现 fetch 同步请求

    使用 async 和 await,实现 fetch 同步请求 关于 async 和 await 的介绍https:...

  • ES2017 async 函数

    async 和 await 在干什么 每个名称都有意义async : 异步await: async wait简...

  • async-await

    一、async-await和Promise的关系 async-await是promise和generator的语法...

  • 小程序-云开发

    async和await async:异步(无等待)await:等待(是为了同步) 一、await 关键字只在 as...

  • async / await

    async / await 优缺点 async 和 await 相比直接使用 Promise 来说,优势在于处理 ...

  • flutter中compute和isolate

    async和await:对于普通的任务,使用async和await可实现异步处理任务,而async的处理方式并非使...

  • Promise 执行顺序

    使用 async 和 await

网友评论

      本文标题:async和await

      本文链接:https://www.haomeiwen.com/subject/hxonoftx.html