ฉันจะใช้ async GM_xmlhttpRequest เพื่อคืนค่าในลำดับเดิมได้อย่างไร

Jan 03 2021

ฉันกำลังพยายามสร้างสคริปต์ Tampermonkey เพื่ออัปเดตวันที่ในบางไซต์ ฉันได้รับอาร์เรย์ของ id จากเว็บไซต์ และขอข้อมูลจากมันด้วย id ของอาร์เรย์ หลังจากนั้นฉันต้องส่งคืนข้อมูลของอินพุตแต่ละรายการ

เนื่องจากฟังก์ชันคือasyncจะส่งคืนข้อมูลในลำดับแบบสุ่ม แต่ฉันต้องการอาร์เรย์ใหม่เหล่านั้นเพื่อส่งคืนในลำดับเดิม ฉันได้ลอง sync และPromises แล้ว แต่อันแรกช้าเกินไปและฉันไม่เข้าใจอันที่สอง

ฉันสามารถจัดเรียงรหัสได้ แต่ฉันยังได้วันที่ซึ่งอยู่ในลำดับของอาร์เรย์แรกด้วย ดังนั้นฉันจึงไม่รู้ว่าจะจัดลำดับเดียวกันกับอาร์เรย์รหัสที่สองได้อย่างไร

นี่คือรหัส:

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

คุณสามารถใช้ Promises เพื่อดำเนินการ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()ฟังก์ชันที่มีการส่งคืนสัญญา ซึ่งได้รับการแก้ไขเมื่อสำเร็จ GET แต่ถูกปฏิเสธเมื่อล้มเหลว

awaitรอให้ Promise ตกลงก่อนที่จะดำเนินการต่อไป และที่tryมีอยู่เพื่อตรวจจับการปฏิเสธ Promise (หาก GET ล้มเหลว)

ข้อมูลอ้างอิง:

  • Promiseใน MDN
  • awaitใน MDN