Обратные вызовы становятся действительно уродливыми, если вам нужно объединить несколько из них, поэтому Promises были изобретены, чтобы упростить это.Чтобы использовать Promises в вашем случае, вы должны сначала создать Promise при запросе базы данных¹:
const query = q => new Promise((resolve, reject) => mysqli.query(q, (err, result) => err ? reject(err) : resolve(result)));
Теперь выполнение нескольких запросов вернет несколько обещаний, которые можно объединить, используя Promise.all
, в одно обещание²:
async getList(){
const communities = await query("SELECT * FROM communities");
const result = await/*³*/ Promise.all(communities.map(async community => {
const host = await query(`SELECT name FROM users WHERE id='${community.host}'`);/*⁴*/
return {
...community,
hostName: host[0].name,
};
}));
return result;
}
Теперь вы можете легко получить результат с помощью:
new Communities().getList().then(list => {
console.log(list);
});
Читать дальше:
Работа с обещаниями - Разработчики Google
Понимание async / await - Ponyfoo
Примечания:
¹: если вы делаете это чаще, вам, вероятно, лучше использовать библиотеку mysql, которая поддерживает обещанияизначально это экономит много работы.
²: благодаря этому запросы выполняются параллельно , что означает, что это намного быстрее, чем выполнять один за другим (что может быть сделаноиспользуя цикл for и ожидая внутри него).
³: await
лишнее, но я предпочитаю оставить его для пометки как асинхронного действия.
⁴: я полагаюэто также можно сделать с помощью одного запроса SQL, такесли он слишком медленный для вашего варианта использования (в чем я сомневаюсь), вам следует оптимизировать сам запрос.