Нужно написать функцию, которая получает массив всех пользователей и передает его в функцию коллбэк.
Пример использования:
getUsersInfo((users) => {
console.log(users); // [ { name: 'Alex', age: 70 }, { name: 'Elon' } ]
});
Для получения данных вам предоставлены 2 асинхронные функции
getUsersIds
- возвращает массив с идентификаторами пользователей.
getUserInfo
- возвращает данные пользователя по заданному идентификатору:
getUsersIds((ids) => {
console.log(ids); // ['id2', 'id6']
});
getUserInfo('someUserId', (userInfo) => {
console.log(userInfo); // { name: 'Alex', age: 70 }
});
Функция должна вызвать callback, переданный первым аргументом и передать туда массив данных о пользователях.
Порядок пользователей в результирующем массиве должен соответствовать порядку идентификаторов в массиве из getUsersIds
Решение должно быть следующего формата:
const { getUserInfo, getUsersIds } = db;
function getUsersInfo(onLoad) {
// код решения
}
Callback-hell во всей красе. :)
// const { getUserInfo, getUsersIds } = db;
// Демо функции, чтобы работало
const data = {
id1: {name: 'Alice', age: 62},
id2: {name: 'Bob', age: 28},
id3: {name: 'Charlie', age: 10},
};
function getUsersIds(cb) {
setTimeout(() => cb(Object.keys(data)), 100);
};
function getUserInfo(id, cb) {
setTimeout(() => cb(data[id]), 10*data[id].age);
}
function getUsersInfo(onLoad) {
// Начнём с получения идентификаторов
getUsersIds(ids => {
// Пустой массив, если пользователей нет
if (ids.length === 0) return onLoad([]);
// Подготовим массив необходимой длины
const users = [];
users.length = ids.length;
// Счётчик коллбеков, нужен чтобы среагировать на последний
let c = ids.length;
// Перебираем идентификаторы, запускаем «асинхронные» функции
// for (const [i, id] of Object.entries(ids)) {
for(let i = 0; i < ids.length; ++i) {
const id = ids[i];
getUserInfo(id, user => {
// Кладём полученного пользователя в нужное место в массиве
users[i] = user;
// Когда счётчик дошёл до нуля, вызываем onLoad
if (!--c) onLoad(users);
});
}
});
}
getUsersInfo(users => console.log(JSON.stringify(users)));
А теперь попробуем это облагородить)
// const { getUserInfo, getUsersIds } = db;
// Демо функции, чтобы работало
const getUsersIds = (cb) => cb([1, 2, 3]);
const getUserInfo = (id, cb) => cb({1: {name: 'Alice'}, 2: {name: 'Bob'}, 3: {name: 'Charlie'}}[id]);
// Функция, улучшающая интерфейс предоставленных функций
const promisify = fn => (...args) =>
new Promise((resolve) => fn(...args, res => resolve(res)));
let getUsersIds$ = promisify(getUsersIds);
const getUserInfo$ = promisify(getUserInfo);
// Promise-реализация, чтобы не менять интерфейс функции, необходимой по ТЗ
async function getUsersInfo$() {
const ids = await getUsersIds$();
return await Promise.all(ids.map(id => getUserInfo$(id)));
}
function getUsersInfo(onLoad) {
getUsersInfo$().then(onLoad)
}
// Вызов функций
getUsersInfo(users => console.log(JSON.stringify(users)));
setTimeout(() => {
getUsersIds$ = () => Promise.resolve([]);
getUsersInfo(users => console.log(JSON.stringify(users))); // []
}, 1000);
Есть несколько асинхронных функций которые вызываются вот так:
Есть динамический роут, который выводит отфильтрованный список товаров, фильтрация происходит в getter во vuex, все бы ничего, но если перезагрузить...