From c94ca721b548b57b0bd750ea0d40e7adf6b4a979 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Wed, 25 Jul 2018 23:18:19 -0700 Subject: [PATCH] Do a better job of managing http requests --- src/App.js | 40 +++++++++++++++++++++++++++++++------ src/LoadQueue.js | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 src/LoadQueue.js diff --git a/src/App.js b/src/App.js index f948bba0..9a15885c 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,7 @@ import React from "react"; import skins from "./skins.json"; import "./App.css"; +import LoadQueue from "./LoadQueue"; const hashes = Object.keys(skins); @@ -12,14 +13,37 @@ const SKIN_RATIO = SKIN_HEIGHT / SKIN_WIDTH; class Skin extends React.Component { constructor(props) { super(props); - this.state = { loaded: false }; + this.state = { loaded: false, load: false }; + this._controller = new window.AbortController(); this._handleLoad = this._handleLoad.bind(this); } + componentDidMount() { + this._dequeue = this.props.queue.enqueue(() => { + const signal = this._controller.signal; + return fetch(this.props.src, { signal }) + .then(() => { + this.setState({ load: true }); + }) + .catch(e => { + console.log("aborted?", e); + }); + }, 0); + } + _handleLoad() { this.setState({ loaded: true }); } + componentWillUnmount() { + if (!this.state.loaded) { + this._controller.abort(); + } + if (this._dequeue != null) { + this._dequeue(); + } + } + render() { return (
- + {this.state.load && ( + + )}
); @@ -75,6 +101,7 @@ class App extends React.Component { scrollDirection: null }; this._handleScroll(); + this._queue = new LoadQueue(10); this._handleScroll = this._handleScroll.bind(this); this._handleResize = this._handleResize.bind(this); } @@ -135,6 +162,7 @@ class App extends React.Component { const left = column * columnWidth; skinElements.push( { + this._remove(priority, cb); + }; + } + _run() { + if (this._free === 0) { + return; + } + const priority = this._queue.findIndex(value => Boolean(value)); + if (priority === -1) { + // The queue is empty + return; + } + this._free--; + const set = this._queue[priority]; + const values = set.values(); + const cb = values.next().value; + + cb().finally(() => { + this._free++; + this._run(); + }); + + this._remove(priority, cb); + } +}