I have tried to use a window.setTimeout
but I get an error at runtime:
Error on line 182: TypeError: window.setTimeout is not a function. (In
window.setTimeout(function(){ }, 3000);
,
window.setTimeout
is undefined) (-2700)
Can someone help me ?
I have tried to use a window.setTimeout
but I get an error at runtime:
Error on line 182: TypeError: window.setTimeout is not a function. (In
window.setTimeout(function(){ }, 3000);
,
window.setTimeout
is undefined) (-2700)
Can someone help me ?
Share Improve this question edited Jun 17, 2016 at 7:49 Mermoz asked Jun 15, 2016 at 11:54 MermozMermoz 511 silver badge4 bronze badges 6- 2 can you please post your code? – Jordi Castilla Commented Jun 15, 2016 at 11:55
- 1 Fairly descriptive error message. So you do not have setTimeOut in JXA - perhaps delay() will work – mplungjan Commented Jun 15, 2016 at 11:59
- Or remove the window. from it since there is no window – mplungjan Commented Jun 15, 2016 at 12:05
- setTimeout(function(){ alert("working"); }, 1000); I have tried to run it in Apple script Editor and I get the same error: Error on line 1: ReferenceError: Can't find variable: setTimeout – Mermoz Commented Jun 15, 2016 at 12:42
- github./dtinth/JXA-Cookbook/issues/19 – mplungjan Commented Jun 16, 2016 at 5:41
3 Answers
Reset to default 8First, JXA does not have window
as the global object because it is not a browser.
You can access the global object via the top level this
or, more simply, omit the global object to access the global variables and functions directly.
this.Math.sin(1)
// or
Math.sin(1)
Second, JXA has no support for setTimeout
currently.
This is the essential reason why you got the error that setTimeout
is undefined.
However, you can emulate setTimeout
with its Objective-C bridge.
This is an example implementation of setTimeout
with NSTimer
.
Note that working with NSTimer
in JXA requires to start NSRunLoop
manually.
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)
There is a global delay(seconds)
function you can call.
...
delay(0.2);
...
See: https://github./dtinth/JXA-Cookbook/wiki/System-Events#example-of-sending-copy-mand
There is nothing asynchronous in JXA. You can use delay(3)
, but nothing else executes.
You can fire off another task with $.system("yourCommand &")
, it runs asynchronously. Here is a little demo that speaks asynchronously. It could be another script that does whatever you need
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
}
}