簡體   English   中英

在進入下一次迭代之前等待

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM