【问题标题】:setTimout with Javascript for automation使用 Javascript 实现自动化的 setTimeout
【发布时间】:2016-10-16 12:40:28
【问题描述】:

我尝试使用window.setTimeout,但在运行时出现错误:

第 182 行出错:TypeError: window.setTimeout 不是函数。 (在

window.setTimeout(function(){

}, 3000);

,window.setTimeout 未定义) (-2700)

有人可以帮我吗?

【问题讨论】:

  • 您能发布您的代码吗?
  • 相当描述性的错误消息。所以你在 JXA 中没有 setTimeOut - 也许 delay() 会起作用
  • 或者删除窗口。从它,因为没有窗户
  • setTimeout(function(){ alert("working"); }, 1000);我试图在 Apple 脚本编辑器中运行它,我得到了同样的错误:第 1 行错误:ReferenceError:找不到变量:setTimeout

标签: javascript javascript-automation


【解决方案1】:

你可以调用一个全局的delay(seconds)函数。

...
delay(0.2);
...

见:https://github.com/dtinth/JXA-Cookbook/wiki/System-Events#example-of-sending-copy-command

【讨论】:

    【解决方案2】:

    首先,JXA 没有window 作为全局对象,因为它不是浏览器。 您可以通过顶级this 访问全局对象,或者更简单地说,省略全局对象直接访问全局变量和函数。

    this.Math.sin(1)
    // or
    Math.sin(1)
    

    其次,JXA 目前不支持setTimeout。 这就是你得到setTimeout未定义错误的根本原因。

    但是,您可以用its Objective-C bridge 模拟setTimeout。 这是setTimeoutNSTimer 的示例实现。 请注意,在 JXA 中使用 NSTimer 需要手动启动 NSRunLoop

    function timer (repeats, func, delay) {
      var args = Array.prototype.slice.call(arguments, 2, -1)
      args.unshift(this)
      var boundFunc = func.bind.apply(func, args)
      var operation = $.NSBlockOperation.blockOperationWithBlock(boundFunc)
      var timer = $.NSTimer.timerWithTimeIntervalTargetSelectorUserInfoRepeats(
        delay / 1000, operation, 'main', null, repeats
      )
      $.NSRunLoop.currentRunLoop.addTimerForMode(timer, "timer")
      return timer
    }
    
    function invalidate(timeoutID) {
      timeoutID.invalidate
    }
    
    var setTimeout = timer.bind(undefined, false)
    var setInterval = timer.bind(undefined, true)
    var clearTimeout = invalidate
    var clearInterval = invalidate
    
    
    setTimeout(function() {
      console.log(123)
    }, 1000)
    
    $.NSRunLoop.currentRunLoop.runModeBeforeDate("timer", $.NSDate.distantFuture)
    

    【讨论】:

      【解决方案3】:

      JXA 中没有任何异步。您可以使用delay(3),但不会执行其他任何操作。

      您可以使用$.system("yourCommand &") 启动另一个任务,它异步运行。这是一个异步说话的小演示。它可能是另一个脚本,可以满足您的任何需求

      ObjC.import("stdlib")
      var app = Application.currentApplication()
      app.includeStandardAdditions = true
      $.system("(sleep 2;say hurry up!)&") // see the difference when you remove the &
      prompt("are you ready?", "yes")
      function prompt(text, defaultAnswer) {
        var options = { defaultAnswer: defaultAnswer || "" }
        try {
          return app.displayDialog(text, options).textReturned
        } catch (e) {
          return null
        }
      }
      

      【讨论】:

      • 好的,谢谢您的回答。但是延迟调用会触发系统调用,我想延迟刷新应用程序的 UI(或 JS setInterval)。很高兴现在 JXA 中没有任何异步内容。
      • 我猜你唯一的选择是阻塞延迟(2)。作为一个有点异步的人,我觉得这很恶心。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-18
      • 1970-01-01
      • 2016-10-10
      • 2021-09-28
      • 2018-11-27
      • 2016-11-27
      • 2017-11-13
      相关资源
      最近更新 更多