如何使javascript FOR LOOP在循环之前等待某些条件 [英] How to make a javascript FOR LOOP wait for certain conditions before looping

查看:87
本文介绍了如何使javascript FOR LOOP在循环之前等待某些条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to call up a function (checkImdb) that will fetch some info from a php file (temp.php) and put some contents on a div (placeToFetchTo). This has to be done a certain amount of times, so I used a FOR LOOP for that. The problem is that only the last instance of the looped counter (currentCastId) gets used. I understand there needs to be a way to force the FOR LOOP to wait for the fetch to be complete, and I have been looking online for answers but nothing seems to work so far. I apologise if I have missed an eventual answer that already exists. Any help is appreciated. This is the code I am referring to:

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() {
}

推荐答案

2017更新:原始答案的回调arg为函数签名中的最后一个arg.但是,既然ES6传播算子是真实的东西,最佳实践是将其放在 first 而不是 last 上,以便可以使用传播算子捕获所有内容"其他".

2017 update: The original answer had the callback arg as last arg in the function signature. However, now that the ES6 spread operator is a real thing, best practice is to put it first, not last, so that the spread operator can be used to capture "everything else".

如果您需要执行任何等待",则您实际上并不想使用for循环.相反,请使用自终止递归:

You don't really want to use a for loop if you need to do any "waiting". Instead, use self-terminating recursion:

/**
 * 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函数是您的实际代码.

In this code the doAsynchronousStuff function is your actual code.

使用requestAnimationFrame是为了确保调用不会淹没调用堆栈.由于这项工作在技术上是独立的,因此我们可以将其安排为在下一刻".

The use of requestAnimationFrame is to ensure the call doesn't flood the callstack. Since the work is technically independent, we can schedule it to be called "on the next tick" instead.

呼叫链有点像这样:

// 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>

这篇关于如何使javascript FOR LOOP在循环之前等待某些条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆