[英]How to stop a loop with setTimeout() method
I have created a route in my REST API that produces a random food order for the user after they send a request with a bunch of parameters.我在我的 REST API 中创建了一个路由,在用户发送带有一堆参数的请求后,它会为用户生成一个随机的食物订单。 I have a while loop that loops through potential options and places them into the
randomOrder
array.我有一个 while 循环,它遍历潜在的选项并将它们放入
randomOrder
数组。 The loop will run until there are as many items in the random order as numberOfHeads
specified by the user.循环将一直运行,直到随机顺序中的项目数量与用户指定的
numberOfHeads
一样多。 The issue is that sometimes it is impossible to create an order that has something for all mouths to feed and as a result, the loop will run forever.问题是,有时不可能创建一个让所有嘴巴都可以喂食的订单,因此,循环将永远运行。 As a backstop for this, I would like to add two conditions to the while loop
作为对此的支持,我想在 while 循环中添加两个条件
If the amount of items in the random order array matches the numberOfHeads
specified by the user then the loop can stop.如果随机顺序数组中的项目数量与用户指定的
numberOfHeads
匹配,则循环可以停止。
if it tried to do this for a number of seconds but finds itself looping infinitely, I want the loop to stop and simply serve up what it has managed to place in the randomOrder
array.如果它尝试这样做几秒钟但发现自己无限循环,我希望循环停止并简单地提供它已设法放置在
randomOrder
数组中的内容。 I have tried to implement this with the setTimeout()
method but I can't seem to get it to change the keepCalling
Boolean from true
to false
in order to stop the loop.我试图用
setTimeout()
方法来实现它,但我似乎无法让它将keepCalling
Boolean 从true
更改为false
以停止循环。 I am also not sure if I can feed two conditions into a while loop where if either condition becomes true the loop stops?我也不确定是否可以将两个条件输入到 while 循环中,如果任一条件为真,则循环停止?
// RANDOM ORDER FILTER/GENERATOR
router.get("/randomorder", async (req, res) => {
//USERS CHOSEN CATEGORIES SPH & NOP SENT THROUGH THE REQUEST
const restCats = await req.body.restcategories
const menueCats = await req.body.menuecats
var totalSpend = await req.body.totalspend
const numberOfHeads = await req.body.numberofheads
const spendPerHead = totalSpend / numberOfHeads
console.log(spendPerHead)
let restOptions = await Restaurant.aggregate(
[{
$match: {
categories: {
$in: restCats
}
}
}]
)
let randomRestOption = restOptions[Math.floor(Math.random() * restOptions.length)];
//RESULT OF ALL MENUE ITEMS MATCHING USER CATEGORIES
let menueOptions = []
//FULL RESULT OF BOTH RESTURANTS MATCHING USERS CHOSEN CATEGORIES AND MENUE ITEMS OF THOSE RESTURANTS MATCHING USERS CATEGORIES
// LOOPS THROUGH ALL RESTURANT OPTIONS MENUES AND OUTPUTS MENUE ITEMS MATCHING THE USERS CHOSEN CATEGORIES
randomRestOption.menue.filter(function checkoptions(option) {
for (let x = 0; x < option.categories.length; x++) {
// console.log(option)
if (option.categories[x] === menueCats[0] || option.categories[x] === menueCats[1] || option.categories[x] === menueCats[2] || option.categories[x] === menueCats[3] || option.categories[x] === menueCats[4] || option.categories[x] === menueCats[5] || option.categories[x] === menueCats[6]) {
// FILTERS RESULTS BASED ON TOTAL SPEND PER HEAD CHOSEN BY USER
if (option.price <= spendPerHead) {
menueOptions.push(option)
} else if (spendPerHead === undefined) {
menueOptions.push(option)
}
}
}
})
var keepCalling = true
const myTimeout = setTimeout(reAssign, 3000)
function reAssign() {
keepCalling = false
}
myTimeout
let randomOrder = []
console.log(keepCalling)
while (randomOrder.length < numberOfHeads || keepCalling === true) {
// console.log(keepCalling)
let randomMenueOption = menueOptions[Math.floor(Math.random() * menueOptions.length)];
// console.log(randomMenueOption)
function checkDuplicates() {
let duplicate = ""
let itemName = randomMenueOption.name
// console.log(itemName)
for (let i = 0; i < randomOrder.length; i++) {
if (itemName === randomOrder[i].name) {
duplicate = "duplicate"
}
// console.log("loop running")
}
// console.log(randomOrder)
return duplicate
}
let checkduplicate = checkDuplicates()
if (checkduplicate === "duplicate") {
// console.log("Found Duplicate")
} else {
randomOrder.push(randomMenueOption)
}
randomOrder.length;
// console.log(randomMenueOption)
}
// console.log(spendPerHead)
try {
res.status(201).send({
randomOrder
})
} catch (err) {
console.log(err)
}
})
setTimeout
is an asynchronous
that means that it will be executed by the event loop
when the call stack
is empty . setTimeout
是asynchronous
的,这意味着它将在call stack
为空时由event loop
执行。
So in your use case it will never will execute because the loop will occupy the call stack
.因此,在您的用例中,它将永远不会执行,因为循环将占用
call stack
。
If you want to get the same effect, you can use the Date
object to capture the current time, and in each iteration in the check if it passed the timeTocancel
.如果你想得到同样的效果,你可以使用
Date
对象来捕获当前时间,并在每次迭代中检查它是否通过了timeTocancel
。
let keepCalling = true;
const startingTime = Date.now();
const timeTocancel = 3000;
while (keepCalling) {
const currentTime = Date.now();
if (currentTime - startingTime >= timeTocancel ) break;
console.log("do things");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.