Come posso utilizzare async GM_xmlhttpRequest per restituire i valori nell'ordine originale?

Jan 03 2021

Sto cercando di creare uno script Tampermonkey per aggiornare le date su qualche sito. Ho ricevuto un array di ID da un sito e sto richiedendo dati da esso con l'ID dell'array. Dopodiché, devo restituire i dati di ciascun Input.

Poiché la funzione è async, restituisce i dati in un ordine casuale, ma ho bisogno che quei nuovi array tornino nell'ordine originale. Ho provato a sincronizzare Promisees, ma il primo è troppo lento e non ho capito il secondo.

Posso ordinare gli ID, ma ho anche ottenuto le date che sono nell'ordine del primo array, quindi non so come ottenere lo stesso ordine del secondo array di ID.

Ecco il codice:

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);
}

Risposte

double-beep Jan 04 2021 at 18:01

È possibile utilizzare Promesse per eseguire le GETrichieste in un ordine specifico. Ecco un esempio:

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 questo esempio, ho creato una makeGetRequest()funzione con restituisce una promessa, che viene risolta in caso di successo GET, ma rifiutata in caso di fallimento.

awaitattende che la Promessa si stabilizzi prima di andare avanti ed tryesiste per rilevare il rifiuto della Promessa (se il GET fallisce).

Riferimenti:

  • Promisesu MDN .
  • awaitsu MDN .