1

我必须调用一个函数 (checkImdb),该函数将从 php 文件 (temp.php) 中获取一些信息并将一些内容放在 div (placeToFetchTo) 上。这必须完成一定次数,所以我为此使用了 FOR LOOP。问题是只有循环计数器(currentCastId)的最后一个实例被使用。我知道需要一种方法来强制 FOR LOOP 等待获取完成,我一直在网上寻找答案,但到目前为止似乎没有任何效果。如果我错过了已经存在的最终答案,我深表歉意。任何帮助表示赞赏。这是我指的代码:

function checkImdb (totalCasts) {
    $(function() {
        for (currentCastId = 1; currentCastId <= totalCasts; currentCastId++) {
                //Gets cast IMDB#
                var row = document.getElementById("area2-" + currentCastId)
                row = row.innerHTML.toString();
                var fetchThis = "temp.php?id=" + row + "\ .filmo-category-section:first b a";
                placeToFetchTo = "#area0-" + currentCastId;

                function load_complete() {
                    var filhos = $(placeToFetchTo).children().length, newDiv ="";
                    var nrMoviesMissing = 0, looped = 0;
                            alert("done- "+ placeToFetchTo);

                }

                document.getElementById("area0").innerHTML = document.getElementById("area0").innerHTML + "<div id=\"area0-" + currentCastId + "\"></div>";

                $(placeToFetchTo).load(fetchThis, null, load_complete);

        } //End of: for (imdbLooper = 0; imdbLooper <= totalCasts; imdbLooper++) {

    }); //End of: $(function() {
}
4

2 回答 2

3

2017 年更新:原始答案将回调 arg 作为函数签名中的最后一个 arg。但是,既然 ES6 扩展运算符是真实存在的,最佳实践是将其放在首位,而不是放在最后,这样扩展运算符就可以用于捕获“其他所有内容”。


如果你需要做任何“等待”,你真的不想使用 for 循环。相反,使用自终止递归:

/**
 * This is your async function that "does things" like
 * calling a php file on the server through GET/POST and
 * then deals with the data it gets back. After it's done,
 * it calls the function that was passed as "callback" argument.
 */
function doAsynchronousStuff(callback, ...) {
  //... your code goes here ...

  // as final step, on the "next clock tick",
  // call the "callback" function. This makes
  // it a "new" call, giving the JS engine some
  // time to slip in other important operations
  // in its thread. This basically "unblocks"
  // JS execution.
  requestAnimationFrame(function() {
    callback(/* with whatever args it needs */);
  });
}

/**
 * This is your "control" function, responsible
 * for calling your actual worker function as
 * many times as necessary. We give it a number that
 * tells it how many times it should run, and a function
 * handle that tells it what to call when it has done
 * all its iterations.
 */
function runSeveralTimes(fnToCallWhenDone, howManyTimes) {
  // if there are 0 times left to run, we don't run
  // the operation code, but instead call the "We are done"
  // function that was passed as second argument.
  if (howManyTimes === 0) {
   return fnToCallWhenDone();
  }

  // If we haven't returned, then howManyTimes is not
  // zero. Run the real operational code once, and tell
  // to run this control function when its code is done:
  doAsynchronousStuff(function doThisWhenDone() {
    // the "when done with the real code" function simply
    // calls this control function with the "how many times?"
    // value decremented by one. If we had to run 5 times,
    // the next call will tell it to run 4 times, etc.
    runSeveralTimes(fnToCallWhenDone, howManyTimes - 1);
  }, ...);
}

在此代码中,doAsynchronousStuff函数是您的实际代码。

的用途requestAnimationFrame是确保调用不会淹没调用堆栈。由于该工作在技术上是独立的,因此我们可以将其安排为“在下一个滴答”上调用。

调用链有点像这样:

// let's say we need to run 5 times
runSeveralTimes(5);
=> doAsynchronousStuff()
   => runSeveralTimes(5-1 = 4)
      => this is on a new tick, on a new stack, so
         this actually happens as if a "new" call:
runSeveralTimes(4)
=> doAsynchronousStuff()
   => runSeveralTimes(4-1 = 3), on new stack
runSeveralTimes(3)
...
=> doAsynchronousStuff()
   => runSeveralTimes(1-1 = 0), on new stack
runSeveralTimes(0)
=> fnToCallWhenDone()
=> return
<end of call chain>
于 2013-11-01T16:03:04.160 回答
0

您需要使用 while 循环并仅在所有提取完成后才退出循环。

function checkImdb (totalCasts) {
 currentCastId = 1;
 totalCasts = 3;
 doneLoading = false;

 while (!doneLoading)
 { 
       //do something
       currentCastId++;

      if (currentCastId == totalCasts)
           doneLoading = true;
 }
}
于 2013-11-01T16:03:32.287 回答