如何通过内部循环等待函数完成

时间:2017-09-15 18:36:56

标签: autohotkey

在下面的脚本中,我尝试运行一系列命令。但是当按下F1运行时,命令将立即运行两个SendAndLoopFor()调用,而不等待内循环完成。

我试图通过在函数内部添加一个返回“”来强制执行此操作,并使用它来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

1 个答案:

答案 0 :(得分:0)

您的问题似乎源于对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