Greasy Fork is available in English.

Dyskusje » Greasy Fork Feedback

Help with making a function wait until all GM_xmlhttpRequest requests are fully completed

§
Napisano: 18-10-2015
Edytowano: 18-10-2015

Help with making a function wait until all GM_xmlhttpRequest requests are fully completed

I've been trying to make a script that generates a list of only the bugs related to Firefox for desktop in Mozilla Mercurial pushlogs.
It's basically an attempt to create lists similar to the "The Official Win32 xxxxxxx builds" found in Firefox Builds • mozillaZine Forums but for any date interval.

It's this: Mozilla Mercurial - Filters changelogs(pushlogs)
(I've set it as 'unlisted' for obvious reasons)
In it's description there I explain how it works.

In essence it does the following:

  • gets all bug links in the page and de-duplicates them
  • retrieves the page for each bug, and extracts the relevant title, status, product and component values.
  • then it filters out the irrelevant bugs from the list
  • then it sorts it based on the product: component (concatenated) string
  • finally it displays the results using a jQuery dialog.
    During the procedure, you may open the Web Console (Ctrl+Shift+K) for progression log.

So, what it does (related to the problem I face) is:

  • calls the getUnique function
  • calls the retrieveValues function for each unique URL (gets the target HTML page via GM_xmlhttprequest and extracts the relevant values)
  • calls the filterBugs function on each the unique bug entries
  • etc...etc

i.e. it's this code:

getUnique();                                            // Get the unique linkes in the page

for (i = 0; i < unique.length; i++) {                   // Retrieves the values for each bug (from it's bug target HTML page)
  retrieveValues(unique[i],i);  
}

for (i = 0; i < unique.length; i++) {                   // Filters the irrelevant bugs out
  filterBugs(unique[i],i);  
}

The problem is that the resulting list is always empty.
It's related to the GM_xmlhttprequest request(s) that's done inside the retrieveValues function.
I have put several logging entries in the script (as you may see in Web Console while it's running)
and it reveals that the filterBugs function is called before all GM_xmlhttprequest (i.e. all retrieveValues calls) are fully completed,
(though I have set the GM_xmlhttprequest request(s) to be done **synchronously)
and so, all filtering is done on "empty values",
so all bugs are wrongly filtered out.

Could you help me with this, please?

woxxomMod
§
Napisano: 18-10-2015
Edytowano: 18-10-2015

The simplest solution would be to check if the currently processed index is the last in xhr onload function:

function retrieveValues(url, index) {
    var thisIndex = index;
    ...............
    xhr.onload = function(r) {
        .............
        if (thisIndex == unique.length -1) {
            onComplete();
        }
    };
    ................
    xhr.send();
}

function onComplete() {
    for (i = 0; i < unique.length; i++) {                   // Filters the irrelevant bugs out
        filterBugs(unique[i],i);  
    }
    ................
}

There's a lot of info and examples you can find on different methods for the asynchronous code.

§
Napisano: 18-10-2015
Edytowano: 18-10-2015

Thanks a lot for your reply.

(I'd prefer the synchronous mode for now, as it's simpler)

So, I updated the code, according to your suggestion,
(I omitted the send command -- I initially tried adding details.send(); but it gave details.send is not a function )
but the issue unfortunately remains.

woxxomMod
§
Napisano: 18-10-2015
Edytowano: 18-10-2015

As for synchronous XHR, stop using it, it's very bad and on its way to being deprecated.

The issue in your code is probably because you didn't make i local as shown in my example.

§
Napisano: 26-10-2015

I've just finished the script Mozilla Mercurial - Filters changelogs:
based on your advice now works in async mode, too.

Thanks a lot for your help!

PS. You're so right: sync mode is very bad

Odpowiedz

Zaloguj się, by odpowiedzieć.