【问题标题】:Wait before moving on to next iteration在继续下一次迭代之前等待
【发布时间】:2020-04-08 00:10:40
【问题描述】:

我有一个函数可以从一个元素中打印出文本,然后是从另一个网页请求的元素中的文本。

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);


}

问题是当我运行它时,需要一些时间才能从其他网页获得回复,但循环继续执行而没有得到回复并打印出结果。我想等到元素打印出来后再继续循环的下一次迭代。

【问题讨论】:

标签: javascript jquery html request


【解决方案1】:

这里的问题是同步代码(即 for 循环)和异步代码(fetch() 网络请求)的组合,这导致了您注意到的不良行为。解决方案是阻塞(阻止)循环的后续迭代,直到当前迭代中的异步网络调用完成。

有多种方法可以实现这一点 - 一种基于 Promise 的解决方案是使用Promise.all() 评估多个 Promise(即,对于每个循环迭代),以确保所有迭代都在彼此锁定的步骤中执行。请参阅下面的修改后的代码副本,其中包含 cmets 详细说明如何完成此操作:

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);
  });

}

希望有帮助!

【讨论】:

    【解决方案2】:

    您可以使用 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);
    
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-13
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      • 2017-05-19
      相关资源
      最近更新 更多