![](/img/trans.png)
[英]Is there a way to wait for the calculations before moving to next iteration in Javascript
[英]Wait before moving on to next iteration
我有一個函數,可以從元素中打印出文本,然后是從不同網頁請求的元素中打印出文本。
function together(){
var finalString ="";
var x = document.getElementsByClassName("h-userinput");
for (var i = 0; i < x.length; i++) {
var text = x[i].innerText || x[i].textContent;
console.log(text+"\n");
var query = "#ctl00_ContentPlaceHolder_ResultsGrid_TB > tr:nth-child(bbcc) > td.total-score-column";
query = query.replace("bbcc",i+1);
var poop = ((document.querySelector(query)).onclick.toString());
text = poop.replace("javascript:location.href=\'","");
text = text.replace("function onclick(event) {","");
text=text.replace("}","");
text = text.replace("\';","");
text = "https://bartholomew.itslearning.com"+text;
var url = text;
fetch(url)
.then(res => res.text())
.then((responseText) => {
const doc = new DOMParser().parseFromString(responseText, 'text/html');
console.log(doc.querySelector("#qti-choiceinteraction-container > tbody > tr.checkedrow > td.answer > div > label > span > p")+"\n");
})
.catch((err) => {
// There was an error, handle it here
});
}
//console.log(finalString);
}
問題是,當我運行它時,需要一些時間才能從其他網頁獲得回復,但循環繼續執行而沒有獲得回復並打印出結果。 我想等到元素被打印出來,然后再進入循環的下一次迭代。
這里的問題是同步代碼(即 for 循環)和異步代碼( fetch()
網絡請求)的組合,這會導致您注意到的不良行為。 解決方案是阻塞(阻止)循環的后續迭代,直到當前迭代中的異步網絡調用完成。
有多種方法可以實現這一點 - 一種基於 Promise 的解決方案是使用Promise.all()
來評估多個 Promise(即對於每個循環迭代),以確保所有迭代都在彼此鎖定的步驟中執行。 請參閱下面的代碼的修改副本,並附有詳細說明如何完成此操作的注釋:
function together() {
var finalString = "";
// Define local helper function that performs iteration logic. We've
// basically moved the logic from for loop into this "iteration
// function". A key point to note is that function returns the
// promise generated by fetch()
function asyncIteration(hUserInput) {
var text = hUserInput.innerText || hUserInput.textContent;
console.log(text + "\n");
var query = "#ctl00_ContentPlaceHolder_ResultsGrid_TB > tr:nth-child(bbcc) > td.total-score-column";
query = query.replace("bbcc", i + 1);
var poop = ((document.querySelector(query)).onclick.toString());
text = poop.replace("javascript:location.href=\'", "");
text = text.replace("function onclick(event) {", "");
text = text.replace("}", "");
text = text.replace("\';", "");
text = "https://bartholomew.itslearning.com" + text;
var url = text;
return fetch(url) // Important to "return" this promise, which has
// the effect of "blocking" iteration until the
// fetch responds
.then(res => res.text())
.then((responseText) => {
const doc = new DOMParser().parseFromString(responseText, 'text/html');
console.log(doc.querySelector("#qti-choiceinteraction-container > tbody > tr.checkedrow > td.answer > div > label > span > p") + "\n");
// Combine all response text into final string to illustrate
// iteration of each async request in lock step
finalString += responseText + " ";
})
.catch((err) => {
// There was an error, handle it here
});
}
// Obtain an array of all elements with class h-userinput
var hUserInputs = Array.from(document.getElementsByClassName("h-userinput"));
// Map each element to a promise by function above. This has
// the effect of performing the fetch for each element
// asynchronously. When each per-iteration fetch has completed, the
// message below will be logged to console
Promise.all(hUserInputs.map(asyncIteration)).then(() => {
console.log("All iterations complete", finalString);
});
}
希望有幫助!
您可以使用 async 和 await 使其更簡單。 只需將 async 添加到您的函數並使用 await 處理 fetch。
async function together(){
var finalString ="";
var x = document.getElementsByClassName("h-userinput");
for (var i = 0; i < x.length; i++) {
var text = x[i].innerText || x[i].textContent;
console.log(text+"\n");
var query = "#ctl00_ContentPlaceHolder_ResultsGrid_TB > tr:nth-child(bbcc) > td.total-score-column";
query = query.replace("bbcc",i+1);
var poop = ((document.querySelector(query)).onclick.toString());
text = poop.replace("javascript:location.href=\'","");
text = text.replace("function onclick(event) {","");
text=text.replace("}","");
text = text.replace("\';","");
text = "https://bartholomew.itslearning.com"+text;
var url = text;
try{
let res = await fetch(url)
let responseText = res.text()
const doc = new DOMParser().parseFromString(responseText, 'text/html');
console.log(doc.querySelector("#qti-choiceinteraction-container > tbody > tr.checkedrow > td.answer > div > label > span > p")+"\n");
}
catch{ console.log('Error')}
}
//console.log(finalString);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.