Наконец, я смог его решить. Благодаря Zim84 ваш указатель фактически решил мою проблему, kudos !!
var results_array = [];
var num = 0;
var promises = [];
console.log(ldap_data);
ldap_cmd_array.forEach(element => {
var myldap = ldap_data.slice(); //to copy a javascript object
myldap.push({
"name": "cmd",
"value": element
});
var dObject = new $.Deferred();
console.log(++num);
promises.push(dObject);
ajaxCall(myldap, 'taaa',
// success callback
function (data) {
console.log(--num);
dObject.resolve();
results_array.push(data);
console.log('pass');
},
//error callback
function (err) {
//Do nothing
dObject.resolve();
console.log(--num);
console.log('fail');
}
);
});
$.when.apply($, promises)
.then(function () {
console.log('I should print after all promises');
console.log(results_array);
});
Сначала давайте определим функцию, которая будет возвращать случайное число от min
(включительно) до max
(исключение). Мы можем сделать это, потому что min
всегда будет установлен на 0, а max
всегда будет установлен на длину нового списка - 1
const random = curry((min, max) => Math.floor(Math.random() * (max - min) - min));
Тогда нам нужна функция, которая будет принимать список и возвращает две вещи (в массиве):
const takeFromList = converge(
converge(pair, [nth, flip(remove)(1)]) [compose(random(0), length), identity]);
Сбор всего вместе:
Как вы можете видеть, если запрошенный размер выборки больше, чем фактический размер списка, он вернет весь список, но в случайном порядке.
const {curry, min, nth, identity, converge, pair, flip, compose, length, remove, flatten} = R;
const random = curry((min, max) => Math.floor(Math.random() * (max - min) - min));
const takeFromList = converge(converge(pair, [nth, flip(remove)(1)]), [compose(random(0), length), identity]);
const sampleSize = curry((size, list) => {
const [el, newList] = takeFromList(list);
const len = min(size, list.length);
return len - 1 > 0 ? flatten([el, sampleSize(len - 1, newList)]) : [el];
});
console.log(sampleSize(2, [1,2,3,4,5]));
console.log(sampleSize(2, [1,2,3,4,5]));
console.log(sampleSize(2, [1,2,3,4,5]));
console.log(sampleSize(20, [1,2,3,4,5]));
console.log(sampleSize(20, [1,2,3,4,5]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
Я бы, вероятно, не использовал Рамду для этого. Обратите внимание, что я один из основателей Ramda и большой поклонник. Но Рамда предназначена для функционального программирования. Одним из главных принципов функционального программирования является использование чистых функций, которые не используют входные данные вне своих аргументов и не имеют никаких эффектов, кроме как для возврата значения. Для одного и того же входа они должны всегда возвращать один и тот же результат. Это не будет работать, когда код должен что-то делать случайным образом. 1 sup>
Вы можете использовать код, подобный тому, что делает для этого lodash, версия с ранним возвратом Fisher -Yates shuffle или вы можете использовать что-то подобное, что также сохраняет свои результаты в порядке, указанном в исходном массиве:
const sampleSize = (size, list, collected = []) => size < 1 || list.length < 1
? collected
: size >= list.length
? [...collected, ...list] // or throw error?
: Math.random() < size / list.length
? sampleSize(size -1, list.slice(1), [...collected, list[0]])
: sampleSize(size, list.slice(1), collected)
console.log(sampleSize(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
console.log(sampleSize(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
console.log(sampleSize(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
console.log(sampleSize(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
console.log(sampleSize(10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
console.log(sampleSize(20, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
Это было написано на скорую руку, и может иметь ошибки, но это должно быть довольно близко. Идея состоит в том, чтобы проверять каждый элемент по одному, чтобы увидеть, должен ли он быть включен, корректируя шанс в зависимости от того, сколько осталось включить и сколько осталось в списке.
Версия Фишера-Йейтса была бы более эффективной, чем эта, тем более что в ней используется рекурсия, которая даже сегодня не может быть эффективно оптимизирована двигателями, даже если спецификация требует ее уже несколько лет. Но Фишер-Йейтс не сохраняет первоначальный порядок сортировки. Если вы хотите этого, этот может быть для вас.
1 sup> Обратите внимание, что в какой-то момент у Рамды действительно было расширение случайных чисел , но это давно отброшено. Он использовал воспроизводимый генератор псевдослучайных чисел, который звучит почти как оксюморон, но имеет смысл при работе с чистыми функциями.