You can start with an array of the required values, then either shuffle the array or randomly select values from it. Some say Math.random isn't truely random, but it should be good enough.
The following uses splice to select values, so the loop iterates backwards since splicing shortens the source array each time.
function getRandoms(){
for (var seed=[1,1,1,1,1,2,2,2,2], result=[], i=seed.length; i; i--) {
result.push(seed.splice(Math.random() * i | 0, 1)[0]);
}
return result;
}
// Show randomness of result
(function() {
var s = new Array(30).fill('+');
var r;
for (var i=9; i; ){
document.getElementById(--i).textContent = s.join('');
}
var j = 300; // Number of runs
var delay = 20; // Default delay in ms
function display(lag) {
delay = lag || delay;
getRandoms().forEach(function(v, i, rand) {
var el = document.getElementById(i);
if (v == 1) {
el.textContent = el.textContent.slice(0,-1);
// If run out of "+", add some to every line
if (!el.textContent.length) {
for (var k=0; k < 9; k++) {
document.getElementById(k).textContent += '++++++++++';
}
}
} else {
el.textContent += '+';
}
if (i == 0) {
document.getElementById('msg').innerHTML = 'Remaining: ' + j +
'<br>' + 'Values: ' + rand.join('');
}
});
--j;
if (j > 0) {
setTimeout(display, delay);
}
}
display(50);
}());
// Single call
// console.log(getRandoms().join());
<span id="0"></span><br>
<span id="1"></span><br>
<span id="2"></span><br>
<span id="3"></span><br>
<span id="4"></span><br>
<span id="5"></span><br>
<span id="6"></span><br>
<span id="7"></span><br>
<span id="8"></span><br>
<span id="msg"></span>
For fun I've added a display of the distribution. Each line represents a value in the result array from 0 to 8 and starts with a set number of "+" symbols. Each time a 1 is in the related position, a "+" is removed. Each time a 2 is in the position, a "+" is added. Since there are more 1s than 2s, the lines slowly get shorter. When a line gets to zero length, 10 more "+" are added to every line.
The important part is that the lines stay about equivalent lengths and that the same lines aren't longest or shortest after each run. If you think you see a pattern emerging, it must be sustained for at least 100 runs to show a bias.