非同期 GM_xmlhttpRequest を使用して元の順序で値を返すにはどうすればよいですか?

Jan 03 2021

いくつかのサイトの日付を更新する Tampermonkey スクリプトを作成しようとしています。サイトから ID の配列を取得し、その配列の ID を使用してデータを要求しています。その後、各入力のデータを返す必要があります。

この関数はasyncランダムな順序でデータを返しますが、これらの新しい配列は元の順序で返す必要があります。sync とPromisesを試しましたが、最初は遅すぎて、2 番目はわかりません。

ID を並べ替えることはできますが、最初の配列と同じ順序の日付も取得したので、2 番目の ID 配列と同じ順序にする方法がわかりません。

コードは次のとおりです。

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

回答

double-beep Jan 04 2021 at 18:01

Promise を使用GETして、特定の順序でリクエストを実行できます。次に例を示します。

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

この例makeGetRequest()では、promise を返す関数を作成しました。これは、GET が成功すると解決されますが、失敗すると拒否されます。

awaitPromise が落ち着くのを待ってから次に進み、tryPromise の拒否をキャッチするために存在します (GET が失敗した場合)。

参考資料:

  • PromiseMDN で。
  • awaitMDN で。