OverviewFilesCommitsIssuesDocsReleasesPeers

autobase-doctor / node_modules / signal-promise / index.js

58 lines · javascript ref:
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
}