Created
July 3, 2016 21:24
-
-
Save vikki/de5bf4a11c3ab5fc08189caf01c2e5d7 to your computer and use it in GitHub Desktop.
Element Poller + chooser - Promise based, returns all results (found + not found) - http://jsbin.com/nitohuyilu/1/edit?js,console,output
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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()); | |
let chosenElements = []; | |
function chooseElement(matchedPlacement) { | |
console.log(`choosing with ${matchedPlacement}` ); | |
if (chosenElements.length >= NUMBER_OF_PLACEMENTS_REQUIRED) { | |
console.log(`chosen ${NUMBER_OF_PLACEMENTS_REQUIRED} elements already`); | |
throw new Error('already found something'); | |
} else { | |
console.log(`pushing ${matchedPlacement}` ) | |
chosenElements.push(matchedPlacement); | |
// we only want to cancel all the other pollers | |
// once we've gone over our cap | |
// so we need to check the new length | |
console.log('1'); | |
if (chosenElements.length >= NUMBER_OF_PLACEMENTS_REQUIRED) { | |
console.log('2'); | |
pollers.forEach(poller => { | |
const alreadyFoundEl = chosenElements.find(el => el === poller.selector); | |
console.log(`already found element for poller ${poller.selector}`); | |
if (!alreadyFoundEl) { | |
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', 2000); | |
addElement('foo', 4000); | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment