Skip to content

Latest commit

 

History

History
161 lines (120 loc) · 3.97 KB

Async和Await.md

File metadata and controls

161 lines (120 loc) · 3.97 KB

关于异步处理,ES5 的回调使我们陷入地狱,ES6 的 Promise 使我们脱离魔障,终于、ES7 的 async-await 带我们走向光明。今天就来学习一下 async-await。

基本用法

async function demo() {
  let result = await Math.random()
  console.log(result)
}

demo() // 0.9552660768336405
// 返回一个Promise对象

感觉加没加都一个样,那我还用它干什么 ?

async

async用来表示函数是异步的,定义的函数会返回一个 promise 对象,可以使用 then 方法添加回调函数

async function demo1() {
  return 111
}

demo1().then(val => {
  console.log(val) // 111
})

await

await 可以理解为是 async wait 的简写。await 必须出现在 async 函数内部,不能单独使用!!!

    function errorDemo2() {
        await Math.random()
    }

    errorDemo2()            // 会报错

简单的例子

function demo4(delay1) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('I am demo4')
    }, delay1)
  })
}

function demo5(delay2) {
  console.log('想不到吧')
  setTimeout(() => {
    console.log('I am demo5')
  }, delay2)
}

async function demo6() {
  await demo5(1000)

  console.log('嘻嘻嘻')

  let result = await demo4(2000)
  console.log(result)
}

demo6()

// 想不到吧
// 嘻嘻嘻
// I am demo5
// I am demo4

await 会等待 sleep 函数 resolve ,所以即使后面是同步代码,也不会先去执行同步代码再来执行异步代码。

调用 demo6 函数,它里面遇到了 await, await 表示等一下,代码就暂停到这里,不再向下执行了,它等什么呢?等后面的 promise 对象执行完毕,然后拿到 promise resolve 的值并进行返回,返回值拿到之后,它继续向下执行,而 promise 的.then 是一个异步操作,加入到 task 队列中。换个角度来将,await 之后一定能够拿到 async,也就是 promise 请求后的值

async 和 await 相比直接使用 Promise 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码。缺点在于滥用 await 可能会导致性能问题,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性。

实例

如果看过我 Promise 那篇的,应该还记得“陌生”男人这个梗,继续用 async await 来说这个。

我们需要拿到了用户信息,但是我们还要拿到该用户的聊天列表,然后再拿到跟某一“陌生”男人的聊天记录呢 ?

function handleAjax(params) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: params.url,
      type: params.type || 'get',
      data: params.data || '',
      success: function(data) {
        resolve(data)
      },
      error: function(error) {
        reject(error)
      }
    })
  })
}

async function demo7() {
  let p1 = await handleAjax({ url: './user' })

  let p2 = await handleAjax({
    url: './user/connectlist',
    data: p1.user_id
  })

  let p3 = await handleAjax({
    url: './user/connectlist',
    data: p2.one_man_id
  })
}

demo7()

// 认真观察下代码就能看到。请求是一个结束后,再执行下一个请求。p2等p1执行完,p3等p2执行完

错误处理

reject 情况下我们怎么处理?正确答案是给个 try catch 包裹一下

function demo8(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('I am demo8 ')
    }, delay)
  })
}

async function demo9() {
  let t1 = await demo8(1000)
  console.log(t1)
}

demo9() // I am demo8

// 为了处理Promise.reject 的情况我们应该将代码块用 try catch 包裹一下
async function demo10() {
  try {
    let t1 = await demo8(1000)
    console.log(t1)
  } catch (err) {
    console.log(err)
  }
}

相关链接

来自 segmentfault 的作者一步 : https://segmentfault.com/a/1190000011526612