Skip to content

Instantly share code, notes, and snippets.

@vikki
Created July 3, 2016 21:31
Show Gist options
  • Save vikki/c82ef0e584d9b92ee9c4dd80da1bf5f2 to your computer and use it in GitHub Desktop.
Save vikki/c82ef0e584d9b92ee9c4dd80da1bf5f2 to your computer and use it in GitHub Desktop.
Element Poller + chooser - Streams based, returns all results (found + not found) - http://jsbin.com/mutuziqamu/1/edit?js,console,output
// requires Q
const NUMBER_OF_PLACEMENTS_REQUIRED = 1;
const MS_TO_WAIT = 7000;
const selectors = ['.wibble', '.bleuch', '.foo'];
function checkElement(selector, observer) {
var elementFound = document.querySelector(selector) !== null;
console.log(`el ${selector} = found : ${elementFound}`);
observer.next({found: elementFound, selector: selector});
if (elementFound) {
observer.completed();
}
}
function PollingPromise(selector) {
this.selector = selector;
this.pollerDfd = Q.defer();
this.search = function() {
this.intervalId = window.setInterval(() => {
var elementFound = document.querySelector(selector) !== null;
// console.log(`el ${selector} = found : ${elementFound}`);
if (elementFound){
console.log(`&& resolving ${selector} promise`);
this.pollerDfd.resolve({selector: selector});
window.clearTimeout(this.intervalId);
}
}, 1000);
window.setTimeout(() => {
console.log('^^ timeout');
window.clearTimeout(this.intervalId);
const err = new Error('give up');
err.selector = selector;
this.pollerDfd.reject(err);
}, MS_TO_WAIT);
return this.pollerDfd.promise;
}
this.cancel = function() {
console.log('^^ cancel');
window.clearTimeout(this.intervalId);
const err = new Error('cancel');
err.selector = selector;
this.pollerDfd.reject(err);
};
return this;
}
function createElementPoller(selector) {
return new PollingPromise(selector);
}
const pollers = selectors.map(createElementPoller);
const pollingPromises = pollers.map(poller => poller.search());
function chooseElement(matchedPlacement) {
console.log(`choosing ${matchedPlacement}` );
pollers.forEach(poller => {
const alreadyFoundEl = matchedPlacement === poller.selector;
if (!alreadyFoundEl) {
console.log(`already found element for poller ${poller.selector}`);
poller.cancel();
}
});
return matchedPlacement;
}
const output = pollingPromises.map(promise => {
return promise.then((res) => {
console.log(`found ${res.selector}`);
return res.selector;
})
.then(chooseElement)
.fail((res) => {
console.log(`failed to find ${res}`);
throw new Error(`failed to find ${res}`);
});
});
Q.allSettled(output)
.then(outputArray => {
console.log(outputArray);
});
// ========================
// next part is for testing it
// you'd normally just let the DOM do this
// ========================
(function addTestElements() {
function addElement(name, delay) {
setTimeout(function() {
var p = document.createElement('p');
p.innerText = name;
p.className = name;
console.log(`^^ adding .${name}`)
document.body.appendChild(p);
}, delay);
};
addElement('wibble', 2000);
addElement('bleuch', 3000);
addElement('foo', 4000);
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment