javascript - 带有数据库承诺的javascript递归函数
问题描述
我为此花费了令人尴尬的时间。我可以找到几种可能的解决方案,但似乎无法将它们映射到我的具体情况。基本问题是我对如何管理承诺缺乏了解。这是非常接近的,可能是我可以使用的解决方案,但我有一个变体,使它不能根据需要直接工作。
我的数据库中有一个用户表。任何用户都可以是会员,任何会员都可以有 0 到 n 个推荐人。这些推荐中的任何一个也可以推荐成员。给定一个会员的 member_id,我需要获取他们所有推荐的列表以及他们所有的推荐、推荐......等等,所以这是一个基本的递归问题。挑战是......我似乎无法让承诺交易正确。
使用 api 调用来解决问题:
app.get('/api/calculateReferralTotals', (req, res) => {
const member_id = req.body.member_id;
knex.select('member_id').from('users').where({referred_by:
member_id}).then((referrals) => {
GetReferrals(referrals);
// do something with the global_referral_array but
// have to deal with the promises first
res.status(200).send({final_referral_list});
}).catch((error) => {
console.log("Error in select " + error);
});
});
var global_referral_array = [];
function GetReferrals(referrals) {
referrals.forEach((amb) => {
knex.select('member_id').from('users').where({referred_by:
amb.member_id}).then((ref) => {
if(ref.length>0) {
ref.forEach((element) => {
global_referral_array.push(element.member_id);
});
GetReferrals(ref);
}
}).catch((error) => {
});
});
递归函数符合我的预期——我得到了一个引用成员 ID 的列表,但显然我必须以某种方式处理异步性质,这就是我被卡住的地方。我以为我可以通过递归构建一组承诺,然后在返回原始调用时解决这些承诺(可能有一个全局承诺数组),但这似乎不起作用。我还尝试将单个 member_id 传递给递归函数并在 DB 调用后继续循环,所以我只处理一次事件,但这也不起作用。
任何指导将不胜感激!
解决方案
asyc
如果你使用函数会容易得多
不确定它是否有效,但我会试试这个:
async function GetReferrals(referrals) {
if(!referrals) return [] // you need a condition to stop recursion
let promises = referrals.map(amb =>knex.select('member_id').from('users').where({referred_by:
amb.member_id}))
let res = await Promise.all(promises)
return [...res, ...res.map(r => await GetReferrals(r)) ]
});
并在主要通话中:
GetReferrals(referrals).then( result =>
// do something with the global_referral_array but
// have to deal with the promises first
res.status(200).send({final_referral_list});
)
推荐阅读
- fortran - 计算距离函数的有效方法
- mysql - MySQL 清理孤儿表 innoDB
- sql - 如何比较hive和sql表
- python - 如何在 SQL 中使用转义字符通过 LIKE 进行查询?(Python)
- javascript - 使用 jQuery concat 添加新行
- python - 如何在 python kivy gui 中显示 OpenStreetMap?
- reactjs - 我们如何从 antd 的下拉菜单中选择多选
- c++ - C++:如何对同一个数据类使用不同的方法实现?
- autodesk-forge - 通过数据管理 API 在 BIM360 中列出模型文件
- ios - 我可以仅在没有私钥的情况下使用证书和 embedded.mobileprovision 辞职 ipa 吗?