gpt4 book ai didi

javascript - 无法访问 for 循环中使用的链式 promise 内的外部作用域变量

转载 作者:行者123 更新时间:2023-12-03 22:23:16 25 4
gpt4 key购买 nike

我需要在 async/await 里面做 for..loop ,但那样我就不能做并行操作。
所以我将这些 promise 插入一个变量 promises 稍后我将在它上面做 promise.all()。这是我的代码。

const promises = [];
for (let i = 0; i < todayAssignedJobs.length; i += 1) {
promises.push(Leaderboard.findOrCreate({...}).then((leaderboard, created) => {
if (!created) {
const rating = (todayAssignedJobs[i].rating + leaderboard.rating * leaderboard.jobs_completed) / (leaderboard.jobs_completed + 1);
const commission = todayAssignedJobs[i].commission + leaderboard.commission;
const jobsCompleted = leaderboard.jobs_completed + 1;
Leaderboard.update({
rating,
commission,
jobs_completed: jobsCompleted,
updated_by: 'system',
}, {
where: {
id: leaderboard.id,
},
});
}
AssignedJob.update({
is_leaderboard_generated: true,
}, {
where: {
id: todayAssignedJobs[i].id,
},
});
}));
}
await Promise.all(promises)

不知何故,我在执行 Assigned.update({..}, { where: { id: todayAssignedJobs[i].id }}) 时无法获得 id

获取错误:

Unhandled rejection Error: WHERE parameter "id" has invalid "undefined" value



有人可以解释发生了什么吗?另外,请建议我可以在下面做吗?
promises.push(async () => { // I will use await here })

最佳答案

只是对现有答案的一些进一步改进。
Leaderboard.update()AssignedJob.update() 是需要等待的异步函数,因此需要将回调函数转换为 async 函数。这确保在所有数据库操作完成之前不会解析 promise ,而不仅仅是 findOrCreate() :

const promises = todayAssignedJobs.map(async todayAssigned => {
const [leaderboard, created] = await Leaderboard.findOrCreate({...});

if (!created) {
const rating = (todayAssigned.rating + leaderboard.rating * leaderboard.jobs_completed) / (leaderboard.jobs_completed + 1);
const commission = todayAssigned.commission + leaderboard.commission;
const jobsCompleted = leaderboard.jobs_completed + 1;

await Leaderboard.update({
rating,
commission,
jobs_completed: jobsCompleted,
updated_by: 'system',
}, {
where: {
id: leaderboard.id,
},
});
}

await AssignedJob.update({
is_leaderboard_generated: true,
}, {
where: {
id: todayAssigned.id,
},
});
});

await Promise.all(promises);

这种方法的一个更基本的问题是 Leaderboard.findOrCreate()Leaderboard.update() 不是单个事务的一部分。这是有问题的,因为 update() 取决于 leaderboard 中条目的当前值,由于条目的 non-atomic 修改,这会在您的数据库中创建竞争条件:
const rating = (todayAssigned.rating + leaderboard.rating * leaderboard.jobs_completed) / (leaderboard.jobs_completed + 1);
const commission = todayAssigned.commission + leaderboard.commission;
const jobsCompleted = leaderboard.jobs_completed + 1;

每个方法都需要标记为单个事务的一部分。使用 sequelize.js,您可以使用 managed transaction 来实现:
const promises = todayAssignedJobs.map(
todayAssigned => sequelize.transaction(async transaction => {
const [leaderboard, created] = await Leaderboard.findOrCreate({
transaction,
...
});

if (!created) {
const rating = (todayAssigned.rating + leaderboard.rating * leaderboard.jobs_completed) / (leaderboard.jobs_completed + 1);
const commission = todayAssigned.commission + leaderboard.commission;
const jobsCompleted = leaderboard.jobs_completed + 1;

await Leaderboard.update({
rating,
commission,
jobs_completed: jobsCompleted,
updated_by: 'system',
}, {
transaction,
where: {
id: leaderboard.id,
},
});
}

await AssignedJob.update({
is_leaderboard_generated: true,
}, {
transaction,
where: {
id: todayAssigned.id,
},
})
})
);

await Promise.all(promises);

关于javascript - 无法访问 for 循环中使用的链式 promise 内的外部作用域变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61361382/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com