如何等待函数完成时使用内部循环
在下面的脚本中,我尝试运行一系列命令。但是当按F1运行时,命令将立即在两个对方之后运行两个SendAndLoopFor()
调用,而无需等待内部循环完成。如何等待函数完成时使用内部循环
我试图通过在函数内添加一个return“”来强制这个等待,并用它来分配一个变量Foo := SendAndLoopFor()
,但即使那样它也不会等待操作。
有没有办法在执行下一个命令之前等待SendAndLoopFor()
命令的完成?
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#MaxThreadsPerHotkey 13
#SingleInstance
F1::
Done = 0
Toggle := !Toggle
Loop
{
If (!Toggle)
Break
SendAndLoopFor("4", -13600)
SendAndLoopFor("5", -13600)
}
return
SendAndLoopFor(TSend="", Timeout=0)
{
Send %TSend%
SetTimer, LoopLimit, %Timeout%
Loop
{
If(!Toggle)
Break
If(done == 1)
{
done = 0
Break
}
MouseClick, left
sleep 83
}
}
LoopLimit:
Done = 1
Return
您的问题似乎从SetTimer的的误解造成的。这是并行化任务的极好工具,因为在继续执行脚本之前,脚本固有地不会等待计时器。
为了说明这一点,简化脚本并观察相同的效果。
F3::
SetTimer, LoopLimit, -2000
SendInput, This is stuff happening before the timer.{Enter}
return
LoopLimit:
SendInput, This is stuff happening after.
一个简单的解决方案是计数迭代次数和命中计数器限制后杀死循环。
F3::
count = 0
Loop
{
; Do stuff.
count += 1
Sleep, 1000
if (count >= 5)
{
break
}}
您还可以使用various built-in variables比较从循环的开始时间,以你的临界值,但这些都可以一起工作很烦,所以我建议避免它们,除非你的脚本时间内工作敏感的约束。按照意见
编辑:
F1::
Done = 0
Toggle := !Toggle
Loop
{
If (!Toggle)
Break
SendAndLoopFor("4", -13600)
SendAndLoopFor("5", -13600)
Sleep, 2000
}
return
SendAndLoopFor(TSend="", Timeout=0)
{
Send %TSend%
SetTimer, LoopLimit, %Timeout%
Loop
{
If(!Toggle)
{
SendInput, This is inside the Toggle.{Enter}
Break
}
If(done == 1)
{
SendInput, This is inside the Done.{Enter}
done = 0
Break
}
SendInput, This is after the If statements.{Enter}
MouseClick, left
Sleep, 999999 ; Note how this has no effect due to above break.
}
}
LoopLimit:
Done = 1
这不是循环部分,但我有一个问题。它是函数调用的链。 'SendAndLoopFor(“4”,-13600)',它内部循环它的'点击'命令,因为它应该。但同时另一个'SendAndLoopFor(“5”,-13600)'也被调用。无需等待第一次调用完成。 –
@MXD我不假设你有机会测试循环中的每个条件语句吗? SendAndLoopFor'内部的'If(!Toggle)'总是为真,因此循环总是中断。因为你没有睡眠命令,延迟时间足够长,所以它们似乎在同一时间触发,但情况并非如此。他们只是快速完成。我将修改你的代码来编辑我的答案以展示这一点。 –
有效地,我以相同的方式在另一个脚本中使用If(!Toggle)。它的工作原理很好。 https://gist.github.com/anonymous/36e75336eec880016bc6aef81861edcf(完整脚本)我上面的代码示例使用了完全相同的代码,但将复制粘贴代码提取到函数中,使代码更干燥。同样,如果'Toggle语句永远是真的,它不会开始运行。考虑到它也在第一个循环中,一个调用这些命令。 –
您需要SendAndLoopFor之前返回()。而你指的是一个不存在的标签,名为LoopLimit –
啊,我确实忘了包括那件。稍后编辑它 –
AutoHotkey会按顺序运行它们,但是您的'SendAndLoopFor'循环只有83毫秒的“睡眠”时间。这是故意的吗?因为你目前的延迟几乎感觉不到。 –