How can I check if a JavaScript function is fully executed without a callback function?
I am scripting for Adobe Illustrator and use the "save()" method to save my active Document. When it's done saving I want to do something, but only after its completely saved.
The method doesn't offer a callback function so I need another way to execute my own function, after the document is saved.
Which SDK do you use? Probably documentAfterSave event is what you need instead?
(described as dcoumentAfterSave (yes, with typo) in programmers-guide.pdf)
Related
Is there a way for me to delay a function call in Google Apps Scripts? I'm currently testing for smaller time frames, but I would eventually like to have a 72-hour wait period between processing data and calling moveRows.
I was trying to achieve this by making this Javascript function call:
setTimeout(function() { moveRows(arrayOfRows); }, 3000);
I also tried doing it with a trigger but my function never got called.
ScriptApp.newTrigger('moveRows(arrayofRows)')
.timeBased()
.everyMinutes(1)
.create()
What am I doing wrong?
As others have pointed out, setTimeout cannot be used in GAS. Instead, you can use the function [Utilities.sleep()][1] (see this answer).
setTimeout() belongs to the 'window' object that is not present in GAS. Remember, the code is compiled on Google servers, not in your browser, so you don't have access to DOM in this environment. Similarly, you can't reference 'document' or other DOM objects. The only place where it's possible is client-side HTML that HtmlService creates and sends to your browser for rendering.
You can only pass function name as parameter to the newTrigger() method. You are passing the parameter, which is why it doesn't work.
Is there a way for me to delay a function call in Google Apps Scripts? I'm currently testing for smaller time frames, but I would eventually like to have a 72-hour wait period between processing data and calling moveRows.
I was trying to achieve this by making this Javascript function call:
setTimeout(function() { moveRows(arrayOfRows); }, 3000);
I also tried doing it with a trigger but my function never got called.
ScriptApp.newTrigger('moveRows(arrayofRows)')
.timeBased()
.everyMinutes(1)
.create()
What am I doing wrong?
As others have pointed out, setTimeout cannot be used in GAS. Instead, you can use the function [Utilities.sleep()][1] (see this answer).
setTimeout() belongs to the 'window' object that is not present in GAS. Remember, the code is compiled on Google servers, not in your browser, so you don't have access to DOM in this environment. Similarly, you can't reference 'document' or other DOM objects. The only place where it's possible is client-side HTML that HtmlService creates and sends to your browser for rendering.
You can only pass function name as parameter to the newTrigger() method. You are passing the parameter, which is why it doesn't work.
If you use plain script tags on an HTML page, rendering is blocked until the script has been downloaded and parsed. To avoid that, for faster page display, you can add the 'async' attribute, which tells the browser to continue processing down the page without waiting for that script. However, that inherently means that other javascript that refers to anything in that script will probably crash, because the objects it requires don't exist yet.
As far as I know, there's no allScriptsLoaded event you can tie into, so I'm looking for ways to simulate one.
I'm aware of the following strategies to defer running other code until an async script is available:
For a single script, use their 'onload' event or attribute. However, there's no built-in way I know of to tell when ALL scripts have loaded if there's more than one.
Run all dependent code in onload event handlers attached to the window. However, those wait for all images too, not just all scripts, so the run later than would be ideal.
Use a loader library to load all scripts; those typically provide for a callback to run when everything has loaded. Downside (besides needing a library to do this, which has to load early), is that all code has to wrapped in a (typically anonymous) function that you pass into the loader library. That's as opposed to just creating a function that runs when my mythical allScriptsLoaded fires.
Am I missing something, or is that the state of the art?
The best you could hope for would be to know if there are any outstanding async calls (XMLHttpRequest, setTimeout, setInterval, SetImmediate, process.nextTick, Promise), and wait for there to not be one. However, that is an implementation detail that is lost to the underlying native code--javascript only has its own event loop, and async calls are passed off to the native code, if I understand it correctly. On top of that, you don't have access to the event loop. You can only insert, you can't read or control flow (unless you're in io.js and feeling frisky).
The way to simulate one would be to track your script calls yourself, and call after all script are complete. (i.e., track every time you insert a relevant script into the event loop.)
But yeah, the DOM doesn't provide a NoAsyncPending global or something, which is what you'd really require.
I've been looking through some code that rewrites window._jqjsp. From the context, it seemed like it was either part of the DOM or something jQuery might insert.
Anyone has a clue what window._jqjsp is?
It's used in jQuery mobile development. It looks to be a special type of callback that passes on data to other callbacks.
"The jQuery JSONP plugin provides the sham callback, defaultly named _jqjsp, whose sole purpose is to make the response data available for the app's actual callback functions."
http://software.intel.com/en-us/articles/jquery-mobile-listview
It's most likely an extension. I know that a few of the Chrome extensions I use inject scripts on the page.
EDIT:
After checking around, it looks like this plugin might be assigning itself to that variable. Are you using jquery-jsonp? This mentions it.
I am creating a userscript for a game that will modify certain parts of a page in real time to help the user know how long they must wait to perform certain actions.
The problem I am running into is that the game has some AJAX already built in, every three seconds it calls the jQuery.getJSON() function to grab information to update things. My script needs to make it appear to the end user as if the page was updating in real time, rather than every 3 seconds. As well as add extra information. Without adding extra requests (the games owners will not like that).
To do this I need to override the default behavior of the page, I need to change the callback function of the jQuery.getJSON() call to add my functionality. Or at least disable it completely so I can write a new one. And it isn't as easy as assigning a new function to the old name, as it has no name, they just build the function within the jQuery.getJSON() call. Is this possible?
The page script is contained in a separate .js file btw, if that makes any difference.
If the jQuery.getJSON() call is assigned to a variable, it will return a jqXHR object, which you can then modify by adding or changing its callbacks.
If it is not exposed as a variable, but instead is simply called like so
... js blah ...
jQuery.getJSON("myurl",function(){
more blah
});
... more blah ...
... then I believe you're up a creek without a paddle, as that becomes an anonymous function call with no handle. The only way, at that point, would be to try to override by loading another script in place over the first one, but I am really uncertain how stable that would leave the browser environment.
See the jQuery reference for http://api.jquery.com/jQuery.getJSON/ and http://api.jquery.com/Types/#jqXHR for more details on how the $.ajax() system works.