Skip to content

Instantly share code, notes, and snippets.

@benjamingr
Created October 31, 2018 15:15
Show Gist options
  • Save benjamingr/81aa5a87cf3bf282c36b2ac0f6f69a5b to your computer and use it in GitHub Desktop.
Save benjamingr/81aa5a87cf3bf282c36b2ac0f6f69a5b 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} <Other /></div>
}
});
const Other = iterate(async function* () {
let ownCounter = 0;
while(true) {
yield <div>{ownCounter++}</div>
await new Promise(r => setTimeout(r, 500));
}
})
const Counter = iterate(async function* () {
let i = 0;
yield <div>Hello!</div>;
while(true) {
yield <PrettyDiv item={i++} />;
await new Promise(r => setTimeout(r, 1000));
}
});
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
}
});
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(e) {
if (backPressure.length) {
backPressure.shift()(Promise.reject(e));
} else {
// todo - push special token to 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 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