Search code examples
javascriptjquerytampermonkeyuserscripts

How can I use async GM_xmlhttpRequest to return values in original order?


I'm trying to make a Tampermonkey script to update dates on some site. I got an array of id's from a site, and I'm requesting data from it with the id of the array. After that, I have to return data of each Input.

As the function is async, it returns data in a random order, but I need those new arrays to return in the original order. I have tried sync and Promises, but the first is too slow and I haven't understood the second.

I can sort ids, but I also got the dates which are in the order of the first Array, so I don't know how to achieve the same order as the second id array.

Here's the code:

id = GM_getValue('id');

for (let i = 0; i < id.length; i++) {
  setTimeout(() => {
      console.log("Updating " + (i + 1) + " Title");

      GM_xmlhttpRequest({
          method: "GET",
          url: "***" + id[i] + "/***",
          onload: function(response) {
            $(response.responseText).find("#main-form :input").each(function(x) {
                if (x == 0) ids.push(parseInt($(this).val()));
                if (x == 1) array.push($(this).val()));
            });
        }
      });
  }, i * 333);
}

Solution

  • You can use Promises to execute the GET requests in a specific order. Here's an example:

    function makeGetRequest(url) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: response => resolve(response.responseText),
                onerror: error => reject(error)
            });
        });
    }
    
    const ids = GM_getValue('id');
    for (const id of ids) {
        try {
            const response = await makeGetRequest("***" + id + "/***");
            // do stuff with response
        } catch (error) {
            // in case the GET request fails
            console.error(
                "Request failed with error code", error.status,
                ". Message is ", error.responseText
            );
        }
    }
    

    In this example, I've created a makeGetRequest() function that returns a promise, which is resolved when the GET request succeeds, and rejected when it fails.

    await waits for the Promise to settle before moving on and the try exists to catch Promise rejection (in case the request fails).

    References: