有人能告诉我如何让 js 代码等到 http 请求完全完成后再转到另一个功能吗?

问题描述 投票:0回答:1

我一直在努力让这段代码正常工作。基本上我正在点击一个 api 来获取值并将它们添加到表中。我的好主意是从对 api 调用的响应中获取即时消息发送的参数,并将它们每次组合在一个数组中,这样它们就不会混淆。我尝试过 async:false,在循环内外使用 promises 的不同变体。

谁能帮我解决这个问题,让我成为一个更好的程序员?我这里有一个简化版本的代码(请注意我使用了一些东西作为示例):

var slotId = [];
var status = [];
var slotFromAjax =[];
var UnAuthIssue;
var AuthIssue;
var AuthStep;
var UnAuthStep;
var TLD;
var mySpace;
var authStepColour;
var authIssueColour;
var unAuthStepColour;
var unAuthIssueColour;
var url;
var slotNumber;
var messages2 = [92578, 95157];



if (document.getElementById("tickets_list_whlist")) {
  var table = document.getElementById("tickets_list_whlist");
} else {
  console.log('no table');
}

function makeHttpRequest(messages2) {
 
  return new Promise((resolve, reject) => {
    var promises = [];
    for (var k = 0; k < messages2.length; k++) {
      promises.push(
        new Promise((resolve, reject) => {
         
            GM.xmlHttpRequest({
            method: "GET",
            url:
             "example.com/api/"+messages2[k],
            headers: {
              "Content-Type": "application/json",
              "Origin": "https://example.com", // replace with your domain
            },
            onload: (response) => {
              if (response.status == 200) {
                var NewJson = JSON.parse(response.responseText);
                if (NewJson.collection[0].schemas[1] !== undefined) {
                  slotNumber = NewJson.collection[0].slot;
                  if (NewJson.collection[0].schemas[0].workflow == "Yes") {
                    AuthStep = NewJson.collection[0].schemas[0].step;
                    UnAuthStep = NewJson.collection[0].schemas[1].step;
                    AuthIssue = NewJson.collection[0].schemas[0].issue;
                    UnAuthIssue = NewJson.collection[0].schemas[1].issue;
                  }

                  if (AuthStep) {
                    if (
                      AuthStep == "Complete"
             
                    ) {
                      if (UnAuthIssue === undefined) {
                        UnAuthIssue = "No issue";
                      } else if (
                        AuthIssue == "" ||
                        AuthIssue == null ||
                        AuthIssue == ""
                      ) {
                        AuthIssue = "No Issue";
                        authStepColour = "green";
                        authIssueColour = "black";
                      }

                               slotFromAjax.push([slotNumber, AuthStep]);
                    }
                  }
                }
                resolve(response);
              } else {
                reject(response);
              }
            },
            onerror: (error) => {
              reject(error);
            },
          });
        })
      );
    }
    Promise.all(promises)
      .then(() => {
        resolve(slotFromAjax);
      })
      .catch((error) => {
        reject(error);
      });
  });
}

function firstFunction() {
  console.log("Running first function");
  return makeHttpRequest(messages2);
}

function secondFunction(data) {
  // This function runs second and depends on the data returned by the HTTP request
  console.log("Running second function with data:", data);
  return Promise.resolve();
}

function thirdFunction() {
  console.log("Running third function");
}

// Call the functions in order using Promises
firstFunction()
  .then((data) => {
    return secondFunction(data);
  })
  .then(() => {
    thirdFunction();
  })
  .catch((error) => {
    console.error(error);
    console.log("Error outer promise");
  });
javascript promise xmlhttprequest
1个回答
0
投票

如果我可以稍微调高一点,那么我会这样做: 有点未经测试...

const slotFromAjax = []
const ids = [92578, 95157]

const table = document.getElementById('tickets_list_whlist') ?? console.log('no table')

/** @type {fetch} */
function ittyFetch(url, init = {}) {
  return new Promise((rs, rj) => {
    const xhr = GM.xmlHttpRequest({
      method: init.method || 'GET',
      url,
      responseType: 'blob',
      headers: Object.fromEntries(new Headers(init?.headers).entries()),
      data: init.body || '',
      onload (result) {
        rs(new Response(result.response, {
          status: result.status,
          statusText: result.statusText,
          headers: result.responseHeaders
        }))
      },
      onabort: () => rj(new DOMException('Aborted', 'AbortError')),
      ontimeout: () => rj(new TypeError('Network request failed, timeout')),
      onerror: (err) => rj(new TypeError('Failed to fetch: ' + err.finalUrl))
    })
  })
}

async function makeHttpRequest (id) {
  const res = await ittyFetch(`example.com/api/${id}`, {
    headers: {
      'Content-Type': 'application/json',
      'Origin': 'https://example.com', // replace with your domain
    },
  })
  
  if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`)

  const newJson = await res.json()

  if (newJson.collection[0].schemas[1] !== undefined) {
    const slotNumber = newJson.collection[0].slot
    const [ collection ] = newJson.collection

    if (collection.schemas[0].workflow === 'Yes') {
      let authStep = collection.schemas[0].step
      // let unAuthStep = collection.schemas[1].step
      let authIssue = collection.schemas[0].issue
      let unAuthIssue = collection.schemas[1].issue
      
      if (authStep == 'Complete') {
        if (unAuthIssue == undefined) {
          unAuthIssue = 'No issue';
        } else if (!authIssue) {
          authIssue = 'No Issue'
          // let authStepColor = 'green'
          // let authIssueColor = 'black'
        }
  
        slotFromAjax.push([slotNumber, authStep])
      }
    }

  }
}

async function firstFunction() {
  console.log('Running first function')
  
  // Do one request at a time
  // 
  // const results = []
  // for (const id of ids) results.push(await makeHttpRequest(id))
  
  // Do all request at once (parallel)
  return Promise.all(ids.map(makeHttpRequest))
}

async function secondFunction(data) {
  // This function runs second and depends on the data returned by the HTTP request
  console.log('Running second function with data:', data)
}

async function thirdFunction() {
  console.log('Running third function')
}

firstFunction()
  .then(secondFunction)
  .then(thirdFunction)
  .catch(console.error)
© www.soinside.com 2019 - 2024. All rights reserved.