Skip to content

Instantly share code, notes, and snippets.

@benjamingr
Last active October 31, 2018 14:52
Show Gist options
  • Save benjamingr/5c55e68efd1d154858823aa7c8ef6827 to your computer and use it in GitHub Desktop.
Save benjamingr/5c55e68efd1d154858823aa7c8ef6827 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
const PrettyDiv = iterate(async function* (props) {
for await (const {item} of props) {
yield <div style={{fontSize:30}}>{item}</div>
}
});
const Counter = iterate(async function* () {
yield <div>Hello!</div>;
var i = 0;
while(true) {
yield <PrettyDiv item={i++} />;
await new Promise(r => setTimeout(r, 1000));
}
}, "Counter");
const SpaceStation = iterate(async function* (props) {
// this gets called in the constructor
yield <div>Loading...</div>
try {
let position = await fetch('http://api.open-notify.org/iss-now.json').then(x => x.json());
let { latitude, longitude } = position.iss_position;
yield <div> The ISS is at {latitude} x {longitude} </div>
} catch (e) {
// error handling
yield <div> Error Loading Space Station Location </div>
} finally {
// this gets called on unmount
}
}, "SpaceStation");
function pushedIterator(props) {
const pressure = [props];
const backPressure = [];
let done = false;
return {
next(/* ignored */) {
return new Promise(r => {
if (pressure.length) {
r({value: pressure.shift(), done: false});
} else {
if (done) {
r({value: undefined, done: true});
}
backPressure.push(r);
}
});
},
return() {
done = true;
},
throw() {},
push(value) {
if(pressure.length || !backPressure.length) {
pressure.push(value);
} else {
const resolve = backPressure.shift();
resolve({value, done: false });
}
},
[Symbol.asyncIterator]() {
return this;
}
}
}
function iterate(iterator, name) {
return class Hooked extends Component {
constructor(props) {
super(props);
this.name = name;
this.value = null;
this.propsIterator = pushedIterator(props);
this.iterator = iterator(this.propsIterator);
}
async componentDidMount() {
for await (const item of this.iterator) {
this.value = item;
if(this.value === undefined) debugger;
await new Promise(r => this.forceUpdate(r));
}
}
componentWillUnmount() {
iterator.close();
}
shouldComponentUpdate(nextProps) {
this.propsIterator.push(nextProps);
return false;
}
render() {
return this.value;
}
}
}
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<Counter />
{/* <SpaceStation></SpaceStation> */}
</header>
</div>
);
}
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment