58 lines
1.2 KiB
JavaScript
58 lines
1.2 KiB
JavaScript
module.exports = class Signal {
|
|
constructor () {
|
|
this._resolve = null
|
|
this._reject = null
|
|
this._promise = null
|
|
this._bind = bind.bind(this)
|
|
this._onerror = clear.bind(this)
|
|
this._onsuccess = clear.bind(this, null)
|
|
this._timers = new Set()
|
|
}
|
|
|
|
wait (max) {
|
|
if (!this._promise) {
|
|
this._promise = new Promise(this._bind)
|
|
this._promise.then(this._onsuccess).catch(this._onerror)
|
|
}
|
|
if (max) return this._sleep(max)
|
|
return this._promise
|
|
}
|
|
|
|
_sleep (max) {
|
|
const s = new Promise((resolve, reject) => {
|
|
const done = () => {
|
|
this._timers.delete(state)
|
|
resolve(true)
|
|
}
|
|
const id = setTimeout(done, max)
|
|
const state = { id, resolve, reject }
|
|
this._timers.add(state)
|
|
})
|
|
|
|
return s
|
|
}
|
|
|
|
notify (err) {
|
|
if (!this._promise) return
|
|
const resolve = this._resolve
|
|
const reject = this._reject
|
|
this._promise = null
|
|
if (err) reject(err)
|
|
else resolve(true)
|
|
}
|
|
}
|
|
|
|
function clear (err) {
|
|
for (const { id, resolve, reject } of this._timers) {
|
|
clearTimeout(id)
|
|
if (err) reject(err)
|
|
else resolve(true)
|
|
}
|
|
this._timers.clear()
|
|
}
|
|
|
|
function bind (resolve, reject) {
|
|
this._resolve = resolve
|
|
this._reject = reject
|
|
}
|