美文网首页
认识 async/await、callback()、Promis

认识 async/await、callback()、Promis

作者: 橙色流年 | 来源:发表于2020-08-30 21:10 被阅读0次

async/awaitES7 中用来处理异步回调的一种写法,我们知道以前处理异步回调传统写法都是 callbackpromise 这两种,那么我们可以先来回忆一下 callbackpromise 的写法,在来比较这三者之间的差异。

假设我们定义三个 json 文件,我们知道在 node 中任何文件操作相关的代码都是异步执行的,我们先简单来看下:

// a.json
{
  "next": "b.json",
  "msg": "this is a"
}
// b.json
{
  "next": "c.json",
  "msg": "this is b"
}
// c.json
{
  "next": null,
  "msg": "this is c"
}

项目需求:我们需要先读取 a.json,然后根据 a.jsonnext 值去读取 b.json,依次往下读取......

  • callback

function getFileContent(fileName, callback) {
  // 当前路径,文件夹 files,要读取的文件名  
  const fullFileName = path.resolve(__dirname, 'files', fileName)
  fs.readFile(fullFileName, (err, data) => {
    if (err) {
      console.log(err)
      return
    }
    callback(
      JSON.parse(data.toString())
  )
})
// 利用 callback 来实现
getFileContent('a.json', aData => {
  console.log('a data:', aData.msg)
  getFileContent(aData.next, bData => {
    console.log('b data:', bData.msg)
    getFileContent(bData.next, cData => {
      console.log('c data:', cData.msg)
    })
  })
})

callback 回调地狱肯定都知道,如果这是一个5层回调乃至10层,基本写着写着我们就绕晕了.......让我们来认识一下更优雅的写法 Promise

  • Promise

// 首先将代码封装成 Promise 写法
function getFileContent(fileName) {
  const fullFileName = path.resolve(__dirname, 'files', fileName)
  return new Promise((resolve, reject) => {
    fs.readFile(fullFileName, (err, data) => {
      if (err) {
        reject(err)
        return
      }
      resolve(
        JSON.parse(data.toString())
      )
    })
  })
}
// 使用 Promise 的 then() 方法链式调用来执行
getFileContent('a.json').then(aData => {
  console.log('a data:', aData.msg)
  return getFileContent(aData.next)
}).then(bData => {
  console.log('b data:', bData.msg)
  return getFileContent(bData.next)
}).then(cData => {
  console.log('c data:', cData.msg)
})

可以看到 Promise 通过 then() 的回调方法处理异步请求结果更优雅,不会出现嵌套的回调地狱。不了解 Promise 写法的可以去看我写的 Promise基础详解

既然有了 Promise 写法,那么新出的 async/await 又是什么鬼呢,其实我们可以把它理解为 Promise 的一种语法糖写法,因为 await 其实等待执行的还是必须是一个 Promise,还是来看栗子吧

// 首先将代码封装成 Promise 写法,这一步和 Promise 中一样
function getFileContent(fileName) {
  const fullFileName = path.resolve(__dirname, 'files', fileName)
  return new Promise((resolve, reject) => {
    fs.readFile(fullFileName, (err, data) => {
      if (err) {
        reject(err)
        return
      }
      resolve(
        JSON.parse(data.toString())
      )
    })
  })
}

// 使用 async/await 来实现
async function getReadFile() {
  let aData = await getFileContent('a.json')
  let bData = await getFileContent(aData.next)
  let cData = await getFileContent(bData.next)

  console.log(aData.msg)
  console.log(bData.msg)
  console.log(cData.msg)
}

getReadFile()

上面我们优化了一下写法,将打印放在了最下面,因为它里面没有写任何回调函数,所以async/await 更像是将异步当成了同步来处理,使得我们的代码可以写的更优雅。这里我们要认识:

  • async 后面必修要跟一个函数
  • await 后面必须跟一个 Promise 对象,获取 resolve 的值
  • 两者必须配套书写,await 必须包裹在 async 函数里,
  • async 函数执行返回的也是一个 Promise 对象
  • try-catch 截获 promise 中的 reject 的值
// async 返回的也是一个 Promise 对象,如下:
getReadFile().then(res => {
  console.log(111)
})
// try-catch 截获 promise 中 reject 的值
// aData 中并不存在 next1,通过 try cantch 来进行校验
async function getReadFile() {
  tyr {
    let aData = await getFileContent('a.json')
    let bData = await getFileContent(aData.next1)
    let cData = await getFileContent(bData.next)
  } catch (err) {
    console.log(err)
    console.log(111)
  }
}
getReadFile()

所以说我们可以把它理解为 Promise 的一个语法糖,写到这里,小伙伴应该清楚了吧~~~

相关文章

网友评论

      本文标题:认识 async/await、callback()、Promis

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