Wie kann ich async GM_xmlhttpRequest verwenden, um Werte in der ursprünglichen Reihenfolge zurückzugeben?

Jan 03 2021

Ich versuche, ein Tampermonkey-Skript zu erstellen, um Daten auf einer Website zu aktualisieren. Ich habe ein Array von IDs von einer Site erhalten und fordere Daten mit der ID des Arrays an. Danach muss ich Daten von jedem Eingang zurückgeben.

Da die Funktion ist async, gibt sie Daten in einer zufälligen Reihenfolge zurück, aber ich brauche diese neuen Arrays, um in der ursprünglichen Reihenfolge zurückzugeben. Ich habe sync und Promises ausprobiert , aber das erste ist zu langsam und das zweite habe ich nicht verstanden.

Ich kann IDs sortieren, aber ich habe auch die Daten erhalten, die in der Reihenfolge des ersten Arrays liegen, daher weiß ich nicht, wie ich die gleiche Reihenfolge wie beim zweiten ID-Array erreichen kann.

Hier ist der 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);
}

Antworten

double-beep Jan 04 2021 at 18:01

Sie können Promises verwenden, um die GETAnforderungen in einer bestimmten Reihenfolge auszuführen . Hier ist ein Beispiel:

id = GM_getValue('id');

function makeGetRequest(url) {
  return new Promise((resolve, reject) => {
    GM_xmlhttpRequest({
      method: "GET",
      url: url,
      onload: function(response) {
        resolve(response.responseText);
      },
      onerror: function(error) {
        reject(error);
      }
    });
  });
}

for (let i = 0; i < id.length; i++) {
  console.log("Updating " + (i + 1) + " Title");
  try {
    const response = await makeGetRequest("***" + id[i] + "/***");
    $(response).find("#main-form :input").each(function(x) { if (x == 0) ids.push(parseInt($(this).val()));
      if (x == 1) array.push($(this).val());
    });
  } catch (error) { // in case the GET request fails
    console.error("Request failed with error code", error.status, ". Message is ", error.responseText);
  }
}

In diesem Beispiel habe ich eine erstellte makeGetRequest()Funktion mit Renditen ein Versprechen, das wird aufgelöst auf GET Erfolg, aber abgelehnt , im Fehlerfall.

awaitwartet, bis sich das Promise erledigt hat, bevor es weitergeht, und tryexistiert, um die Ablehnung des Promises abzufangen (wenn GET fehlschlägt).

Verweise:

  • Promiseauf MDN .
  • awaitauf MDN .