我正在制作一个Discord Bot,它将通过Bloxy.js库连接到ROBLOX API。
我正在浏览用户的朋友列表,并检查他们的朋友列表中的朋友是否在代码中提到的四个组之一中-如果存在,它将名称存储在名为“ leoUsernames”的数组中。循环完成后,我希望它记录“记录的所有用户名”。进入控制台。
但是因为我是JS的新手,并且JS的运行方式不像我以前使用的编程语言那样,所以我陷入了困境,而且我不知道该如何使用它来等待检查循环用户需要完成后才能输出“已记录所有用户名”。
代码如下:
function CMD_LEOFRIENDS(message,args){
let leoUsernames = new Array();
if(isNaN(args[1])){
bloxyClient.getIdByUsername(args[1]).then(userId =>{
bloxyClient.getFriends({
userId: userId,
}).then(friends=>{
friends.map(totalfriends=>{
let username = totalfriends.username
let userId = totalfriends.userId
bloxyClient.getUserGroups(userId).then(usergroups=>{
usergroups.map(x=>{
if(x.group.name == "Mayflower State Police" || x.group.name == "Plymouth Police Department" || x.group.name == "Lander Police Department" || x.group.name == "New Haven County Sheriff's Office"){
leoUsernames.push(username)
console.log("Logging username: " + username)
}
}
)
})
});
console.log("All usernames logged.") })
})
}}
预期结果是将当前正在记录的所有用户名记录到控制台。完成记录后,记录“记录了所有用户名”。到控制台。
答案 0 :(得分:1)
在地图中,您正在运行一堆异步代码。由于这一切都是异步发生的,因此地图将完成其循环(尽管仍将有活动的诺言等待完成),然后立即转到console.log
。因此,您需要做的是收集所有的承诺,并等待它们共同完成。确实已经在使用map
真是太好了,因为尽管您现在不返回任何内容(并且很可能原本打算使用forEach
),但这会返回一个数组。
所以,我们可以做的是:
// NOTE: there's almost never a good reason to use `new Array` - it's much slower
let leoUsernames = [];
// NOTE: we save the items (promises) returned by the `map`
const friendPromises = friends.map(totalfriends => {
let username = totalfriends.username;
let userId = totalfriends.userId;
// NOTE: here is where we return each promise
return bloxyClient.getUserGroups(userId).then(usergroups => {
// NOTE: use `forEach` here instead of `map`
usergroups.forEach(x => {
if (
x.group.name == "Mayflower State Police" ||
x.group.name == "Plymouth Police Department" ||
x.group.name == "Lander Police Department" ||
x.group.name == "New Haven County Sheriff's Office"
) {
leoUsernames.push(username);
console.log("Logging username: " + username);
}
});
})
});
// NOTE: wait for all the promises to finish
Promise.all(friendPromises).then(() => {
console.log("All usernames logged.");
});
此外,最好在代码中始终使用分号。虽然在很多情况下从技术上讲是不需要的,但如果不使用它们,则可能会创建一些很难发现的错误。
答案 1 :(得分:1)
如果您可以使用async和await比使用then清洁,它会更干净。然后,您可以正常使用普通循环。
async function CMD_LEOFRIENDS(message, args) {
let leoUsernames = [];
if (isNaN(args[1])) {
let userId = await bloxyClient.getIdByUsername(args[1]);
let friends = await bloxyClient.getFriends({
userId: userId,
});
for (let totalfriends of fiends) {
let username = totalfriends.username;
let userId = totalfriends.userId;
let usergroups = await bloxyClient.getUserGroups(userId);
for (let x of usergroups) {
if (x.group.name == "Mayflower State Police" || x.group.name == "Plymouth Police Department" || x.group.name == "Lander Police Department" || x.group.name == "New Haven County Sheriff's Office") {
leoUsernames.push(username);
console.log("Logging username: " + username);
}
}
}
}
console.log("All usernames logged.");
}
未经测试,但看起来可以正常工作。