JSFiddle - React, Tailwind, and code Playground
JavaScript
const StreamLoaderEvent = {
response: 'response',
complete: 'complete',
error: 'error'
}
function emit (instance, name, data) {
const {_on} = instance
const {_once} = instance
if (_on[name]) {
_on[name].forEach(fct => {
setTimeout(fct.call(instance, data), 0)
})
}
if (_once[name]) {
_once[name].forEach(fct => {
setTimeout(fct.call(instance, data), 0)
})
delete instance.once[name]
}
}
export default class StreamLoader {
static get event () {
return StreamLoaderEvent
}
constructor (url, options) {
const opts = options || {}
this.url = url
this.buffers = {}
this.start = opts.start || 0
this.step = opts.step || 2048
this.end = opts.end || (this.start + this.step - 1)
this._on = {}
this._once = {}
}
range () {
const self = this
return [self.start, self.end]
}
on (name, fct) {
const self = this
if (self._on[name]) {
self._on[name].push(fct)
} else {
self._on[name] = [fct]
}
}
once (name, fct) {
const self = this
if (self._once[name]) {
self._once[name].push(fct)
} else {
self._once[name] = [fct]
}
}
off (name, fct) {
const self = this
const all = self._on[name]
if (all) {
if (!fct) {
// search for fct
for (let i = all.length - 1; i >= 0; i--) {
// we check by reference
const listenerFct = all[i]
if (listenerFct === fct) {
delete all[i]
}
}
} else {
// delete all if no fct is given
delete self._on[name]
}
}
}
load () {
const xhr = new global.XMLHttpRequest()
const self = this
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) {
return
}
const {response} = xhr
const {responseType} = xhr
if (!response || xhr.response.byteLength === 0) {
emit(self, StreamLoaderEvent.complete, self.buffers)
...