根据我的了解async函数就是generator的封装,其本质是一个自执行的generator,并且执行返回一个promise。
co的yield/generator在运用上有一个致命的问题,所有用到yield的环境,必须用一个generator包裹,并且父层也必须使用这种方式,顶层调用时,需要使用co去封装,使其自执行。
那么async/await与yield/generator相比有什么优势吗?顶层调用一个async函数,可以当做普通函数调用?
最近在尝试整合koa v2和socket.io,koa路由就是用async/await方式,调用异步函数完成数据库查询,但是在socket.io上的请求,能不能使用async函数替换普通函数呢,如下: socket.io官方文档的写法:
io.on('connect', (socket) => {
socket.on('join', (roomId) => { // 这是一个普通函数
// 如果这里用到异步调用,或者调用promise,就需要使用callback或then方式
Room.findById(roomId).then((room) => {
console.log(room)
// 如果还有多次异步操作就会导致嵌套层数太深
...
socket.emit('success', room)
})
}
})
异步函数写法(这样写可行吗?)
io.on('connect', (socket) => {
socket.on('join', async (roomId) => { // 这是一个async函数
const room = await Room.findById(roomId).exec()
...
// 可能还有其他await异步调用
socket.emit('success', room)
}
})
写了一个测试,发现确实能够获得a和b两个promise的结果,那说明async函数可以不用await去调用吗?这样写会不会有什么问题?
const p = function (word, t) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(word + ' ' + t)
}, t)
})
}
socket.on('say', async () => {
const a = await p('aaa', 1000)
const b = await p('bbb', 3000)
console.log(a, b)
socket.emit('response', {a, b})
})