queque.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import EventEmitter from "events"
  2. const isNumber = x => typeof x === 'number' && !isNaN(x)
  3. const delay = ms => isNumber(ms) && new Promise(resolve => setTimeout(resolve, ms))
  4. const QUEQUE_DELAY = 5 * 1000
  5. export default class Queque extends EventEmitter {
  6. _queque = new Set()
  7. constructor() {
  8. super()
  9. }
  10. add(item) {
  11. this._queque.add(item)
  12. // console.debug('add item to queque', item, 'in index', this._queque.size)
  13. }
  14. has(item) {
  15. return this._queque.has(item)
  16. }
  17. delete(item) {
  18. this._queque.delete(item)
  19. // console.debug('delete item from queque', item, 'now have', this._queque.size, 'in queque')
  20. }
  21. first() {
  22. return [...this._queque].shift()
  23. }
  24. isFirst(item) {
  25. return this.first() === item
  26. }
  27. last() {
  28. return [...this._queque].pop()
  29. }
  30. isLast(item) {
  31. return this.last() === item
  32. }
  33. getIndex(item) {
  34. return [...this._queque].indexOf(item)
  35. }
  36. getSize() {
  37. return this._queque.size
  38. }
  39. isEmpty() {
  40. return this.getSize() === 0
  41. }
  42. unqueue(item) {
  43. let queque;
  44. if (item) {
  45. if (this.has(item)) {
  46. queque = item
  47. const isFirst = this.isFirst(item)
  48. if (!isFirst) {
  49. throw new Error('Item is not first in queque')
  50. }
  51. } else {
  52. // console.error('try to unqueue item', item, 'but not found')
  53. }
  54. } else {
  55. queque = this.first()
  56. }
  57. if (queque) {
  58. this.delete(queque)
  59. this.emit(queque)
  60. }
  61. }
  62. waitQueue(item) {
  63. return new Promise((resolve, reject) => {
  64. // console.debug('wait queque', item)
  65. if (this.has(item)) {
  66. const solve = async (removeQueque = false) => {
  67. await delay(QUEQUE_DELAY)
  68. // console.debug('wait queque', item, 'done!')
  69. if (removeQueque) this.unqueue(item)
  70. if (!this.isEmpty()) this.unqueue()
  71. resolve()
  72. }
  73. if (this.isFirst(item)) {
  74. // console.debug('wait queque', item, 'is first in queque')
  75. solve(true)
  76. } else this.once(item, solve)
  77. } else {
  78. reject(new Error('item not found'))
  79. }
  80. })
  81. }
  82. }