callback 、promise 、aysnc await 使用

154 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

前言

刚接触 node 开发的时候,对于解决 js 的异步基本使用的都是 callback 方式,后来的 Promise ,再接着就是使用 Generator 函数的语法糖。

callback 回调

回调是将函数当作一个函数的参数进行传递,然后再函数执行完后再执行回调函数。

function sayHi(a,callback){
  console.log('hi')
  callback('done')
}
​
sayHi(1,(data)=>{
    if(data==='done'){
      console.log(`nanlv`)
    }
})

sayHi 函数执行后输出 hi ,接着执行回调函数 ,输出 nanlv。回调函数是个匿名函数,它 被作为参数传递到sayHi 函数里,执行 sayHi 函数后就执行匿名函数。

Promise

ES6中,提出异步编程的另一种解决方案 Promise。Promise 对象是个构造函数,用来生成 Promise实例, then 是 Promise 的方法。

var promise = new Promise((resolve,reject)=>{
  if(true){
  resolve(true)
  } else {
   reject()
  }
}).then(result=>{
  if(result){
    console.log('success')
  }
}).catch((err)=>{
  console.log(err)
})

promise 对象存在三种状态

  • Fullfilled 成功状态
  • rejected 失败状态
  • pending 进行中状态

promise 对象的2个重要方法

  • resolve() 使得 promise 对象的状态变为 成功,同时传递一个参数用于后续操作
  • reject 是将 promise 对象变为失败,同时传递错误信息,由最后的 catch 异常捕获

async/await

Generator 函数的语法糖,可以结合 promise 使用。其实 async 函数就是返回一个 Promise 对象,遇到 await 就先返回,否则就是异步执行。

async function(a){
  var result = await getData(a) //getData是个异步方法,加上 await 后就得获取到数据后才执行 return
  return result;
}

async 是用来定义异步函数,自动将 函数转为 Promise ,函数被调用时返回值都会被 resolve 处理,异步函数内部可以使用 await ,且await只能用在async函数中。遇到 await 时都需要执行完成后才能继续执行。

callback 回调,嵌套回调,经常导致混乱,可读性差,扩展性差。

Promise 是异步编程的另一种解决方案,相比较回调的方式 可读性好点,但是一个长长的链式 then 下去,且如果中间出现错误就会一直 pending,且整个过程无法取消。

所以,async/await 将异步转为同步,避免堵塞也不需要写回调。

转换

callback 回调可以转 promise ,然后就可以使用 async/await

function imcallback(callback){
  // something to do
  // ......
  callback(null,1)
}
​
// converse方法的返回值就是一个 Promise 对象
function converse(){
  return Promise((resolve,reject)=>{
    imcallback((data)=>{
      if(data=1) resolve()
      else reject()
    })
  })
}
​
async function main(){
  const result = await converse();
  return result;
}

Async 函数返回的就是一个promise 函数,所以 converse 方法就可以直接使用 await 控制,得到result 结果后再 return。