我必须调用一个函数(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() {
}
答案 0 :(得分:3)
2017更新:原始答案将回调arg作为函数签名中的最后一个arg。但是,现在ES6扩展运算符是真实的,最好的做法是将它放在第一个,而不是 last ,以便扩展运算符可用于捕获“所有内容其他”。
如果你需要做任何“等待”,你真的不想使用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
的使用是为了确保呼叫不会充斥着callstack。由于工作在技术上是独立的,我们可以安排将其称为“在下一个刻度线上”。
调用链有点像这样:
// 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>
答案 1 :(得分:0)
您需要使用while循环,并且仅在所有提取完成后才退出循环。
function checkImdb (totalCasts) {
currentCastId = 1;
totalCasts = 3;
doneLoading = false;
while (!doneLoading)
{
//do something
currentCastId++;
if (currentCastId == totalCasts)
doneLoading = true;
}
}