一起养成写作习惯!这是我参与「掘金日新计划 · 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。