javascript 具有数据库承诺的递归函数
javascript recursive function with database promises
我在这上面花费了令人尴尬的时间。我可以找到几种可能的解决方案,但我似乎无法将它们映射到我的具体情况。基本问题是我对如何管理承诺缺乏了解。 非常接近并且可能是我可以使用的解决方案,但我有一个变体使其无法根据需要直接工作。
我的数据库中有一个用户 table。任何用户都可以是会员,任何会员都可以有 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) => {
});
});
递归函数如我所料 - 我得到了引用列表 member_id,但显然我必须以某种方式处理异步性质,这就是我遇到的问题。我以为我可以通过递归构建一个 promise 数组,然后在返回到原始调用时解决这些问题(可能有一个全局 promise 数组),但这似乎不起作用。我还尝试将单个 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});
)
这应该有效。
function GetReferrals(member_id) {
return knex.select('member_id').from('users').where({referred_by:
member_id}).then((referrals) => {
const referralIds = referrals.map(element => element.member_id)
return Promise.all(referralIds.map(GetReferrals)).then(referralsReferrals => {
return referralsReferrals.reduce((final, arr) => final.concat(arr), referralIds)
})
})
}
app.get('/api/calculateReferralTotals', (req, res) => {
const member_id = req.body.member_id;
GetReferrals(member_id).then(final_referral_list => {
// do something with the global_referral_array
res.status(200).send({final_referral_list})
}).catch((error) => {
console.log("Error in select " + error);
})
});
我在这上面花费了令人尴尬的时间。我可以找到几种可能的解决方案,但我似乎无法将它们映射到我的具体情况。基本问题是我对如何管理承诺缺乏了解。
我的数据库中有一个用户 table。任何用户都可以是会员,任何会员都可以有 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) => {
});
});
递归函数如我所料 - 我得到了引用列表 member_id,但显然我必须以某种方式处理异步性质,这就是我遇到的问题。我以为我可以通过递归构建一个 promise 数组,然后在返回到原始调用时解决这些问题(可能有一个全局 promise 数组),但这似乎不起作用。我还尝试将单个 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});
)
这应该有效。
function GetReferrals(member_id) {
return knex.select('member_id').from('users').where({referred_by:
member_id}).then((referrals) => {
const referralIds = referrals.map(element => element.member_id)
return Promise.all(referralIds.map(GetReferrals)).then(referralsReferrals => {
return referralsReferrals.reduce((final, arr) => final.concat(arr), referralIds)
})
})
}
app.get('/api/calculateReferralTotals', (req, res) => {
const member_id = req.body.member_id;
GetReferrals(member_id).then(final_referral_list => {
// do something with the global_referral_array
res.status(200).send({final_referral_list})
}).catch((error) => {
console.log("Error in select " + error);
})
});