使用 Async/Await 跳出 while 循环
Break out of while loop with Async/Await
上下文:
我有一个 while 循环,我想 运行 10 次,并且在我有 async/awaait 代码,每 3 秒 运行s。如果 while 循环曾经 运行s 10 次并且 async/await 检查没有 return 预期值,则 while 循环作为一种超时工作,然后跳出 while 循环,进程超时。
问题:代码的循环部分中断 运行ning 首先是 i(循环变量)的值达到最大值。正如我想象的那样,我设置它的方式我无法访问 i 的值,而正在循环并且只有当 i 处于其最大值时。
问题:当条件满足或者我筋疲力尽时,如何尽早跳出这个循环?
var i = 0;
//Run 10 Times
while (i < 10) {
//Run every 3 seconds
((i) => {
setTimeout( async () => {
isAuthenticated = await eel.is_authenticated()();
sessionStorage.sessionStatus = JSON.stringify(isAuthenticated);
console.log('------NEW STATUS-------');
console.log(JSON.parse(sessionStorage.sessionStatus).authenticated);
console.log('Inside:' + i);
}, 3000 * i)
})(i++);
//Break out of loop early if condition is met or I is exhausted, but it only runs 1 time and i is always max
if (i === 9 || JSON.parse(sessionStorage.sessionStatus).authenticated) {
console.log('Outside:' + i);
checkStatus('retried');
break;
}
}
注意:如果有人想知道 eel.is_authenticated()();
不是拼写错误,它是一个用于创建桌面应用程序的 python 库,双 ()() 是正常的。
此外,如果这种方法对于它的作用来说过于复杂,欢迎使用任何其他方法来实现它:)
谢谢
这里的问题是您 运行 立即完成所有循环迭代(10 次),在此过程中设置 10 次超时,彼此间隔 3 秒:
- 你的循环运行了 10 次,造成 10 次超时
- 您达到了
i === 9
个案例
- 3 秒后,第一次超时运行
- 3 秒后,第二次超时运行
- ...
你想要的是让循环在迭代之间实际等待 3 秒。为此,您将以不同的方式使用 setTimeout
- 您将创建一个在达到超时时解决的承诺,并且 await
该承诺:
// As helper function for readability
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
// Your loop
let i;
for (i = 0; i < 10; i++) {
// Wait 3s
await delay(3000);
// Check authentication
const isAuthenticated = await eel.is_authenticated()();
sessionStorage.sessionStatus = JSON.stringify(isAuthenticated);
console.log('------NEW STATUS-------');
console.log(JSON.parse(sessionStorage.sessionStatus).authenticated);
console.log('Inside:' + i);
// Break loop if authenticated
if (isAuthenticated.authenticated) break;
}
// We were authenticated, or looped 10 times
// Note: Because I moved this outside, i will now actually be 10 if the loop
// ended by itself, not 9.
console.log('Outside:' + i);
checkStatus('retried');
这里的一个结果是,如果对 is_authenticated
的调用花费大量时间,则检查间隔 比 3 秒多 ,因为我们是现在等待 3 秒 和 进行此调用。如果这是不希望的,我们可以根据自上次调用以来经过的时间来减少延迟时间:
// As helper function for readability
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
// We will save here when the last delay completed, so that the checks are always
// 3s apart (unless the check takes longer than 3s)
// Initially we save the current time so that the first wait is always 3s, as before
let lastIteration = Date.now();
// Your loop
let i;
for (i = 0; i < 10; i++) {
// Wait until 3s after last iteration (limited to 0ms, negative waits won't work)
await delay(Math.max(lastIteration + 3000 - Date.now(), 0));
// Update "last iteration" time so the next delay will wait until 3s from now again
lastIteration = Date.now();
// Check authentication
const isAuthenticated = await eel.is_authenticated()();
sessionStorage.sessionStatus = JSON.stringify(isAuthenticated);
console.log('------NEW STATUS-------');
console.log(JSON.parse(sessionStorage.sessionStatus).authenticated);
console.log('Inside:' + i);
// Break loop if authenticated
if (isAuthenticated.authenticated) break;
}
// We were authenticated, or looped 10 times
// Note: Because I moved this outside, i will now actually be 10 if the loop
// ended by itself, not 9.
console.log('Outside:' + i);
checkStatus('retried');
所有这一切都假设这段代码所在的函数是async
。如果不是,您需要将其设置为 async
,但您需要记住在调用它时添加一个 .catch(e => handleTheErrorSomehow(e))
,以避免未处理的 promise 拒绝!
上下文: 我有一个 while 循环,我想 运行 10 次,并且在我有 async/awaait 代码,每 3 秒 运行s。如果 while 循环曾经 运行s 10 次并且 async/await 检查没有 return 预期值,则 while 循环作为一种超时工作,然后跳出 while 循环,进程超时。
问题:代码的循环部分中断 运行ning 首先是 i(循环变量)的值达到最大值。正如我想象的那样,我设置它的方式我无法访问 i 的值,而正在循环并且只有当 i 处于其最大值时。
问题:当条件满足或者我筋疲力尽时,如何尽早跳出这个循环?
var i = 0;
//Run 10 Times
while (i < 10) {
//Run every 3 seconds
((i) => {
setTimeout( async () => {
isAuthenticated = await eel.is_authenticated()();
sessionStorage.sessionStatus = JSON.stringify(isAuthenticated);
console.log('------NEW STATUS-------');
console.log(JSON.parse(sessionStorage.sessionStatus).authenticated);
console.log('Inside:' + i);
}, 3000 * i)
})(i++);
//Break out of loop early if condition is met or I is exhausted, but it only runs 1 time and i is always max
if (i === 9 || JSON.parse(sessionStorage.sessionStatus).authenticated) {
console.log('Outside:' + i);
checkStatus('retried');
break;
}
}
注意:如果有人想知道 eel.is_authenticated()();
不是拼写错误,它是一个用于创建桌面应用程序的 python 库,双 ()() 是正常的。
此外,如果这种方法对于它的作用来说过于复杂,欢迎使用任何其他方法来实现它:)
谢谢
这里的问题是您 运行 立即完成所有循环迭代(10 次),在此过程中设置 10 次超时,彼此间隔 3 秒:
- 你的循环运行了 10 次,造成 10 次超时
- 您达到了
i === 9
个案例 - 3 秒后,第一次超时运行
- 3 秒后,第二次超时运行
- ...
你想要的是让循环在迭代之间实际等待 3 秒。为此,您将以不同的方式使用 setTimeout
- 您将创建一个在达到超时时解决的承诺,并且 await
该承诺:
// As helper function for readability
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
// Your loop
let i;
for (i = 0; i < 10; i++) {
// Wait 3s
await delay(3000);
// Check authentication
const isAuthenticated = await eel.is_authenticated()();
sessionStorage.sessionStatus = JSON.stringify(isAuthenticated);
console.log('------NEW STATUS-------');
console.log(JSON.parse(sessionStorage.sessionStatus).authenticated);
console.log('Inside:' + i);
// Break loop if authenticated
if (isAuthenticated.authenticated) break;
}
// We were authenticated, or looped 10 times
// Note: Because I moved this outside, i will now actually be 10 if the loop
// ended by itself, not 9.
console.log('Outside:' + i);
checkStatus('retried');
这里的一个结果是,如果对 is_authenticated
的调用花费大量时间,则检查间隔 比 3 秒多 ,因为我们是现在等待 3 秒 和 进行此调用。如果这是不希望的,我们可以根据自上次调用以来经过的时间来减少延迟时间:
// As helper function for readability
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
// We will save here when the last delay completed, so that the checks are always
// 3s apart (unless the check takes longer than 3s)
// Initially we save the current time so that the first wait is always 3s, as before
let lastIteration = Date.now();
// Your loop
let i;
for (i = 0; i < 10; i++) {
// Wait until 3s after last iteration (limited to 0ms, negative waits won't work)
await delay(Math.max(lastIteration + 3000 - Date.now(), 0));
// Update "last iteration" time so the next delay will wait until 3s from now again
lastIteration = Date.now();
// Check authentication
const isAuthenticated = await eel.is_authenticated()();
sessionStorage.sessionStatus = JSON.stringify(isAuthenticated);
console.log('------NEW STATUS-------');
console.log(JSON.parse(sessionStorage.sessionStatus).authenticated);
console.log('Inside:' + i);
// Break loop if authenticated
if (isAuthenticated.authenticated) break;
}
// We were authenticated, or looped 10 times
// Note: Because I moved this outside, i will now actually be 10 if the loop
// ended by itself, not 9.
console.log('Outside:' + i);
checkStatus('retried');
所有这一切都假设这段代码所在的函数是async
。如果不是,您需要将其设置为 async
,但您需要记住在调用它时添加一个 .catch(e => handleTheErrorSomehow(e))
,以避免未处理的 promise 拒绝!