Created
July 3, 2016 21:31
-
-
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
This file contains 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()); | |
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