我一直在努力让这段代码正常工作。基本上我正在点击一个 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");
});
如果我可以稍微调高一点,那么我会这样做: 有点未经测试...
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)