JSFiddle - React, Tailwind, and code Playground
Emulator with Promises
by herodrigues
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.4.6/bluebird.min.js"></script>
<body>
<div class='network-fake'>
<label><input type='checkbox'> Fake network delay</label>
</div>
<div class='coupon'></div>
<svg class='spinner' viewBox='0 0 100 100' width='20' height='20'>
<circle cx='50' cy='50' r='42' transform='rotate(-90,50,50)' />
</svg>
<br />
<input type="text" id="code" value="">
<input type="button" value="Apply" id="apply" >
</body>
CSS
@-webkit-keyframes spin {
to {
stroke-dashoffset: -264;
}
}
@keyframes spin {
to {
stroke-dashoffset: -264;
}
}
.spinner circle {
fill: none;
stroke: slategray;
stroke-width: 16;
stroke-linecap: round;
stroke-dasharray: 0, 0, 70, 194;
stroke-dashoffset: 0;
animation: spin 1s infinite linear;
-webkit-animation: spin 1s infinite linear;
}
html {
font-family: sans-serif;
line-height: 1.5;
font-size: 14px;
}
h1 {
font-family: Cambria, Georgia, serif;
font-size: 2em;
line-height: 1.3em;
margin: 0 0 0.5em;
}
.network-fake {
display: none;
margin-bottom: 1em;
}
input {
vertical-align: middle;
}
JavaScript
let fakeSlowNetwork;
document.addEventListener('DOMContentLoaded', function() {
const lsKey = 'fake-slow-network';
const networkFakeDiv = document.querySelector('.network-fake');
const checkbox = networkFakeDiv.querySelector('input');
const couponDiv = document.querySelector('.coupon');
fakeSlowNetwork = Number(localStorage.getItem(lsKey)) || 0;
networkFakeDiv.style.display = 'block';
checkbox.checked = !!fakeSlowNetwork;
checkbox.addEventListener('change', function() {
localStorage.setItem(lsKey, Number(checkbox.checked));
location.reload();
});
document.getElementById('apply').addEventListener('click', function () {
const url = 'http://goguru.io/api/v1/coupons?url=http://www.ricardoeletro.com.br&locale=pt-BR';
getStoreData(url).then(JSON.parse).then(function(storeData) {
// Map our array of coupons to an array of coupon json promises
return storeData.coupons.reduce(function(chain, coupon) {
return chain.then(function() {
return simulateClick(coupon);
}).then(function(response) {
addHtmlToPage(coupon.code);
});
}, Promise.resolve());
}).then(function() {
addTextToPage('All done');
}).catch(function(error) {
addTextToPage('Argh, broken: ' + error.message);
}).then(function() {
document.querySelector('.spinner').style.display = 'none';
});
});
function wait(ms) {
return new Promise(function(resolve) {
setTimeout(resolve, ms);
});
}
function getStoreData(url) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = function() {
if (xhr.status == 200) {
resolve(xhr.response);
} else {
reject(Error(xhr.statusText));
}
};
xhr.onerror = function() {
reject(Error("Network Error"));
};
xhr.send();
});
}
function simulateClick(params) {
const...