Skip to content

Instantly share code, notes, and snippets.

@AllanHasegawa
Last active December 10, 2017 18:54
Show Gist options
  • Save AllanHasegawa/8af7be3e9b69c7931b859bd97383038e to your computer and use it in GitHub Desktop.
Save AllanHasegawa/8af7be3e9b69c7931b859bd97383038e to your computer and use it in GitHub Desktop.
RxViz
// Auxiliary code!!!!!
// Ignore and go to "START FROM HERE" below!!!!
function randomInt(min, max) {
min = Math.ceil(min)
max = Math.floor(max)
return Math.floor(Math.random() * (max - min)) + min
}
// Data
function newDataSynchronous(id, source) {
return {
id: id,
instant: randomInt(0, 100),
source: source
}
}
function printData(data) {
const pEle = document.createElement('p')
pEle.innerHTML = JSON.stringify(data)
output.append(pEle)
}
// Button
const buttonEle = document.createElement('button');
buttonEle.innerHTML = "Get Data!";
output.prepend(buttonEle)
function listenButtonClicksObs() {
return Rx.Observable.fromEvent(buttonEle, 'click')
}
function setButtonsState(enable) {
const buttons = output.getElementsByTagName('button');
for (let i = 0; i < buttons.length; i++) {
buttons[i].disabled = !enable
}
}
// Input
function createInputAndListen() {
const input = document.createElement('input')
input.setAttribute('placeholder', 'ID')
output.prepend(input)
return Rx.Observable
.fromEvent(input, 'keyup')
.map(e => e.currentTarget.value)
}
// API
function getApiDataObs(id) {
return Rx.Observable.timer(randomInt(1000, 3000))
.map(() => newDataSynchronous(id, 'API'))
}
// DB
function listenDbDataObs(id) {
return Rx.Observable.range(0, 9999)
.map(() => randomInt(200, 1500))
.concatMap(delay => Rx.Observable.timer(delay))
.map(() => newDataSynchronous(id, 'DB'))
}
// ***************************************
// ***************************************
// ***************************************
// START FROM HERE
// ***************************************
// ***************************************
// ***************************************
// ***************************************
// Exercise 0
// ***************************************
// Here's the info you need to know:
// The data returned by the API:
// Data(val id: Int, val instant: Long, source: String)
const exampleData = {
id: 123,
instant: 1512907154,
source: 'API'
}
// The two functions we will be using:
// Request data from the API
// returns Observable<Data>
getApiDataObs(123)
// Listen for the user's button clicks
// returns Observable<null>
listenButtonClicksObs()
// Tip, copy and past these function calls to the
// end of this code to try them out before composing.
// Now your turn!!!
// Implementar:
// Requisitar dados da API quando user clicar no botão
listenButtonClicksObs()
.do(() => printData("Click!"))
.flatMap(() => getApiDataObs(123))
// ***************************************
// Exercise 1
// ***************************************
// Another function we will use:
// Listen for data changes from the DB.
// returns Observable<Data>
listenDbDataObs(123)
// Now your turn!!!
// Implementar:
// Ao requisitar dados, verificar no DB e na API.
// Porém, retornar apenas o mais recente.
// Ignore o click do botão por enquanto.
listenDbDataObs(123)
.merge(getApiDataObs(123))
.merge(Rx.Observable.interval(500).flatMap(() => getApiDataObs(123)))
.scan((acc, event) => {
const newArray = acc.concat([event]);
newArray.sort((a, b) => b.instant - a.instant);
return newArray.slice(0, 2);
}, [])
.map(arr => arr[0])
.distinctUntilChanged()
// ***************************************
// Exercise 2
// ***************************************
// Now your turn!!!
// Implementar:
// Ao clicar no botão, requisitar dados do DB e da API,
// porém só retornar os dados mais recentes.
const getDataObs = id => listenDbDataObs(id)
.merge(getApiDataObs(id))
.merge(Rx.Observable.interval(500).flatMap(() => getApiDataObs(id)))
.scan((acc, event) => {
const newArray = acc.concat([event]);
newArray.sort((a, b) => b.instant - a.instant);
return newArray.slice(0, 2);
}, [])
.map(arr => arr[0])
.distinctUntilChanged()
listenButtonClicksObs()
.do(() => console.log("Hello"))
.flatMap(() => getDataObs(123))
// ***************************************
// Exercise 3
// ***************************************
// The new function we will be using:
// Creates an input field and listen for changes.
// returns an Observable<string>
//createInputAndListen()
// Now your turn!!!
// Implementar:
// Ao clicar no botão, requisitar dados do DB e da API,
// porém só retornar os dados mais recentes.
const inputObs = createInputAndListen()
.map(it => parseInt(it))
.map(it => {
if (it !== NaN && it > 0) {
return it;
} else {
return NaN;
}
})
.distinctUntilChanged()
listenButtonClicksObs()
.withLatestFrom(inputObs, (a, b) => b)
.filter(it => it !== NaN && it !== null)
.switchMap(id => getDataObs(id).take(2))
// ***************************************
// Exercise 4
// ***************************************
// Ache o erro :) E responda, isso é composição?
function requestData(id) {
setButtonsState(false)
getApiDataObs(id)
.subscribe(result => {
printData(result)
setButtonsState(true)
})
}
listenButtonClicksObs()
.subscribe(() => {
requestData(10)
requestData(11)
})
Rx.Observable.never()
// Auxiliary code!!!!!
// Ignore and go to "START FROM HERE" below!!!!
function randomInt(min, max) {
min = Math.ceil(min)
max = Math.floor(max)
return Math.floor(Math.random() * (max - min)) + min
}
// Data
function newDataSynchronous(id, source) {
return {
id: id,
instant: randomInt(0, 100),
source: source
}
}
function printData(data) {
const pEle = document.createElement('p')
pEle.innerHTML = JSON.stringify(data)
output.append(pEle)
}
// Button
const buttonEle = document.createElement('button');
buttonEle.innerHTML = "Get Data!";
output.prepend(buttonEle)
function listenButtonClicksObs() {
return Rx.Observable.fromEvent(buttonEle, 'click')
}
function setButtonsState(enable) {
const buttons = output.getElementsByTagName('button');
for (let i = 0; i < buttons.length; i++) {
buttons[i].disabled = !enable
}
}
// Input
function createInputAndListen() {
const input = document.createElement('input')
input.setAttribute('placeholder', 'ID')
output.prepend(input)
return Rx.Observable
.fromEvent(input, 'keyup')
.map(e => e.currentTarget.value)
}
// API
function getApiDataObs(id) {
return Rx.Observable.timer(randomInt(1000, 3000))
.map(() => newDataSynchronous(id, 'API'))
}
// DB
function listenDbDataObs(id) {
return Rx.Observable.range(0, 9999)
.map(() => randomInt(200, 1500))
.concatMap(delay => Rx.Observable.timer(delay))
.map(() => newDataSynchronous(id, 'DB'))
}
// ***************************************
// ***************************************
// ***************************************
// START FROM HERE
// ***************************************
// ***************************************
// ***************************************
// ***************************************
// Exercise 0
// ***************************************
// Here's the info you need to know:
// The data returned by the API:
// Data(val id: Int, val instant: Long, source: String)
const exampleData = {
id: 123,
instant: 1512907154,
source: 'API'
}
// The two functions we will be using:
// Request data from the API
// returns Observable<Data>
getApiDataObs(123)
// Listen for the user's button clicks
// returns Observable<null>
listenButtonClicksObs()
// Tip, copy and past these function calls to the
// end of this code to try them out before composing.
// Now your turn!!!
// Implementar:
// Requisitar dados da API quando user clicar no botão
// ***************************************
// Exercise 1
// ***************************************
// Another function we will use:
// Listen for data changes from the DB.
// returns Observable<Data>
listenDbDataObs(123)
// Now your turn!!!
// Implementar:
// Ao requisitar dados, verificar no DB e na API.
// Porém, retornar apenas o mais recente.
// Ignore o click do botão por enquanto.
// ***************************************
// Exercise 2
// ***************************************
// Now your turn!!!
// Implementar:
// Ao clicar no botão, requisitar dados do DB e da API,
// porém só retornar os dados mais recentes.
// ***************************************
// Exercise 3
// ***************************************
// The new function we will be using:
// Creates an input field and listen for changes.
// returns an Observable<string>
//createInputAndListen()
// Now your turn!!!
// Implementar:
// Ao clicar no botão, requisitar dados do DB e da API,
// porém só retornar os dados mais recentes.
// ***************************************
// Exercise 4
// ***************************************
// Ache o erro :) E responda, isso é composição?
/*
function requestData(id) {
setButtonsState(false)
getApiDataObs(id)
.subscribe(result => {
printData(result)
setButtonsState(true)
})
}
() => listenButtonClicksObs()
.subscribe(() => {
requestData(10)
requestData(11)
})
*/
Rx.Observable.from([1, 2, 3])
function printData(data) {
const pEle = document.createElement('p')
pEle.innerHTML = JSON.stringify(data)
output.append(pEle)
}
function opCara() {
printData("OpCara!")
return [1, 2, 3];
}
Rx.Observable
.create(emitter => {
const list = opCara()
list.forEach(it => emitter.next(it))
emitter.complete()
})
.subscribeOn(Rx.Scheduler.async)
/*
Rx.Observable
.from(opCara())
.subscribeOn(Rx.Scheduler.async)
*/
let timeoutIds = []
function getData(callback) {
timeoutIds = []
const list = [1, 2, 3]
list.forEach(it => {
const id = setTimeout(callback.bind(null, it), it * 1000)
timeoutIds.push(id)
})
const id = setTimeout(callback.bind(null, "end"), 5000)
timeoutIds.push(id)
}
function clearGetDataCallback() {
timeoutIds.forEach(id => clearTimeout(id))
}
//getData(item => { printData(item) })
Rx.Observable.never()
Rx.Observable
.create(emitter => {
getData(item => {
printData("Got " + item)
if (item !== "end") {
emitter.next(item)
} else {
emitter.complete()
}
})
return () => { clearGetDataCallback() }
})
.take(2)
Rx.Observable.range(-100, 99999)
.filter(it => it > 0)
.take(15)
.map(it => {
let out = "";
if (it % 3 === 0 && it % 5 === 0) {
out = "FB";
} else if (it % 3 === 0) {
out = "F";
} else if (it % 5 === 0) {
out = "B";
} else {
out = it;
}
return out;
})
let rangeObs = Rx.Observable.range(-100, 99999)
.filter(it => it > 0)
let intervalObs = Rx.Observable.interval(500)
let sourceObs = Rx.Observable.zip(
rangeObs, intervalObs, (a, b) => a)
sourceObs
.take(15)
.map(it => {
let out = "";
if (it % 3 === 0 && it % 5 === 0) {
out = "FB";
} else if (it % 3 === 0) {
out = "F";
} else if (it % 5 === 0) {
out = "B";
} else {
out = it;
}
return out;
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment