Как отмечают другие, фундаментальная проблема заключается в том, что функция, переданная в then
, не передает информацию о местоположении. Код ниже исправляет это. Но это также решает еще одну, более тонкую проблему:
Ваша перетасовка на самом деле не случайна!
Старая статья Роба Вейра подробно объясняет почему это так, но вот краткий глянец этой идеи: ваш тасовщик использует несколько из того, что по сути является броском монеты в вызове на sort
, 50-50 вариантов. Сколько бы из них ни было, количество раз, когда он выбирает одну конкретную комбинацию результатов (скажем, «Alamo Draft House», «Stev ie Ray Vaughn Statue», «Radio Coffee and Beer»), будет отображать некоторую долю время, значение которого должно иметь знаменатель, который является степенью двойки. Он может показывать половину времени, 3/8 или 117/1024 раз. Но он не может отображаться 1/10 времени или 1/60. Монетные сальто не могут вам этого дать. Существует десять различных комбинаций из трех предметов (или 60, если важен порядок). Таким образом, вы не можете случайным образом перетасовать набор предметов, просто подбрасывая монеты. Это реальная проблема, как показывает эта статья.
Наиболее распространенный способ перемешать - это использовать алгоритм Фишера-Йейтса . Приведенный ниже код изменяет это, чтобы прекратить тасование после выбора n
элементов (три для вашего случая.)
Таким образом, этот код исправляет обратный вызов для обещаний и предоставляет метод shuffle
, который справедливо выбирает подмножество .
// Dummy implementation for demo
const locations = new Promise((res, rej) => setTimeout(
() => res([ { name: 'Radio Coffee and Beer', timestamp: 1580676902040, id: '1KALzdUbf7y3ex2C' }, { name: 'ZACH Theater', timestamp: 1580676946375, id: 'Lpxl8xLKCFDKxIhc' }, { name: 'Alamo Draft House', timestamp: 1580676636972, id: 'b5F3Tq2y9cD4WQJq' }, { name: 'Stevie Ray Vaughn Statue', timestamp: 1580676764120, id: 'bIUl4JU7kUSh6eyi' }, { timestamp: 1580676967508, name: 'The Long Center', id: 'xJJOprzYDt3fWqVa' } ]),
50 // 50 ms delay
))
const randoms = (count) => (xs) => {
const arr = xs .slice (0), max = arr.length - 1
for (let i = max; i > max - count; i--) {
const j = Math .floor (Math .random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr .slice (-count)
}
locations
.then ((locs) => randoms (3) (locs))
.then (console .log)