在单线程、同步、非递归代码中,我们可以确定对于任何给定的函数,一次不会有超过一次的调用。
然而,在async/await现实世界中,上述情况不再适用:当我们在执行异步函数 f 期间等待某些内容时,它可能会被再次调用。
我突然想到,使用事件发射器和队列,我们可以为异步函数编写一个包装器,以保证它一次不会有多个调用。像这样的东西:
const events = require('events')
function locked(async_fn) {
const queue = [] // either actively running or waiting to run
const omega = new events()
omega.on('foo', () => {
if (queue.length > 0) {
queue[0].emit('bar')
}
})
return function(...args) {
return new Promise((resolve) => {
const alpha = new events()
queue.push(alpha)
alpha.on('bar', async () => {
resolve(await async_fn(...args))
queue.shift()
omega.emit('foo')
})
if (queue.length === 1) omega.emit('foo')
})
}
}
Run Code Online (Sandbox Code Playgroud)
这个想法是, iff是一个异步函数 then …