2017-09-15 44 views
0

在下面的脚本中,我尝试运行一系列命令。但是当按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 
+0

您需要SendAndLoopF​​or之前返回()。而你指的是一个不存在的标签,名为LoopLimit –

+0

啊,我确实忘了包括那件。稍后编辑它 –

+0

AutoHotkey会按顺序运行它们,但是您的'SendAndLoopF​​or'循环只有83毫秒的“睡眠”时间。这是故意的吗?因为你目前的延迟几乎感觉不到。 –

回答

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 
+0

这不是循环部分,但我有一个问题。它是函数调用的链。 'SendAndLoopF​​or(“4”,-13600)',它内部循环它的'点击'命令,因为它应该。但同时另一个'SendAndLoopF​​or(“5”,-13600)'也被调用。无需等待第一次调用完成。 –

+0

@MXD我不假设你有机会测试循环中的每个条件语句吗? SendAndLoopF​​or'内部的'If(!Toggle)'总是为真,因此循环总是中断。因为你没有睡眠命令,延迟时间足够长,所以它们似乎在同一时间触发,但情况并非如此。他们只是快速完成。我将修改你的代码来编辑我的答案以展示这一点。 –

+0

有效地,我以相同的方式在另一个脚本中使用If(!Toggle)。它的工作原理很好。 https://gist.github.com/anonymous/36e75336eec880016bc6aef81861edcf(完整脚本)我上面的代码示例使用了完全相同的代码,但将复制粘贴代码提取到函数中,使代码更干燥。同样,如果'Toggle语句永远是真的,它不会开始运行。考虑到它也在第一个循环中,一个调用这些命令。 –

相关问题