用setTimeout递归调用一个函数
我想用setTimeout
递归调用几个函数。用setTimeout递归调用一个函数
var flag = 0 ;
function slave1(){
if(flag < 60) {
var COPY_PO_LINE_DIV = document.getElementById("DOM_ELEMENT1"); // Checking if DOM has loaded or not. If yes then doing something.
if (COPY_PO_LINE_DIV != null) {
flag = 0;
//doing something
} else {
setTimeout(slave1,2000); //waiting for 2 seconds and checking again.
}
}
}
//doing similar task
function slave2(){
if(flag < 60) {
var COPY_PO_LINE_DIV = document.getElementById("DOM_ELEMENT2");
if (COPY_PO_LINE_DIV != null) {
flag = 0;
//doing something
} else {
setTimeout(slave2,2000);
}
}
}
function master() {
slave1();
console.log("Without completing slave1 function.");
slave2();
}
通过master()
功能我想打电话给多种功能此起彼伏,然而,在目前的情况下其调用slave2()
没有完成slave1()
。我如何确保slave1()
已执行完成。如果没有加载DOM元素,则应该每2秒执行60次,并且应该从slave1()
开始执行,然后转到下一个。
如果不加载dom元素而没有将控件返回到下一个函数,我想执行60次相同的函数。
您需要调整slave1
以在完成时运行回调,该回调将为slave2
。
function slave1(callback){
if(flag < 60) {
var COPY_PO_LINE_DIV = document.getElementById("DOM_ELEMENT1"); // Checking if DOM has loaded or not. If yes then doing something.
if (COPY_PO_LINE_DIV != null) {
flag = 0;
//doing something
callback();
} else {
setTimeout(slave1,2000); //waiting for 2 seconds and checking again.
}
}
}
function slave2(){...}
function master() {
slave1(slave2);
console.log("Without completing slave1 function.");
}
这是您的基本JavaScript链接。如果您有更多的奴隶你可能想看看async.series
否则你进入回调地狱中的Gabs00已经说得好听:
slave1(function(){
slave2(function(){
slave3(function(){
slave4(slave5);
});
});
});
如果需要值传递给回调,那么你需要使用一个中间匿名函数,该函数继而用所讨论的参数调用预期的回调。要做到这一点,你需要让他们使用的参数定义功能:(?如果有的话)
function slave1(str, callback){...}
function slave3(i, callback){...}
slave1("some argument", function(){
slave2("another argument", function(){
slave3(1, function(){
slave4(2, slave5);
});
});
});
谢谢!有帮助......但假设我连续有5个功能,而不是如何从他们连锁。 – 2014-08-27 11:20:37
@Mike那么你有效地输入回拨地狱,考虑承诺 – Gabs00 2014-08-27 11:23:55
@ Artjom-如果我还必须通过几个参数? – 2014-08-27 13:54:21
你slave2
功能应该传递给slave1
功能作为一个回调,并应在slave1
它完成后调用。由于setTimeout()
函数是异步的,因此您的当前情况非常普遍,因此JS解释器不会等待函数完成,而是会将Echloop循环结束时的setTimeout()
结果设置为并继续处理master()方法。
考虑使用承诺这样的事情。这里是一个在jQuery之上的实现,其他许诺库的工作方式也是类似的。现在
function waitForElement(elementId, maxTries, checkInterval) {
var d = $.Deferred(), intvalID, checkFunc;
// set up default values
maxTries = maxTries || 60;
checkInterval = checkInterval || 2000;
checkFunc = function() {
var elem = document.getElementById(elementId);
if (maxTries-- > 0 && elem) {
clearInterval(intvalID);
d.resolve(elem);
}
if (maxTries <= 0) {
clearInterval(intvalID);
d.reject(elementId);
}
};
// set up periodic check & do first check right-away
intvalID = setInterval(checkFunc, checkInterval);
checkFunc();
return d.promise();
}
,如果你想测试后的又一要素之一,可以级联这样的呼吁:
function master() {
waitForElement("DOM_ELEMENT1").done(function (elem1) {
waitForElement("DOM_ELEMENT2").done(function (elem2) {
alert("elem1 and elem2 exist!");
// now do something with elem1 and elem2
}).fail(function() {
alert("elem1 exists, but elem2 was not found.");
});
}).fail(function() {
alert("elem1 not found.");
});
}
,或者你可以做到这一点并联有一个名为当所有的回调元素的存在:
function master() {
$.when(
waitForElement("DOM_ELEMENT1"),
waitForElement("DOM_ELEMENT2")
)
.done(function (elem1, elem2) {
alert("elem1 and elem2 exist!");
// now do something with elem1 and elem2
})
.fail(function() {
alert("not all elements were found before the timeout");
});
}
为了将参数传递给函数,创建匿名函数证明是一种矫枉过正。考虑使用“绑定”来代替。所以,如果你有
function slave1(str, callback){...}
function slave2(str, callback){...}
function slave3(i, callback){...}
function slave4(i, callback){...}
function slave5()
而不是使用
slave1("some argument", function(){
slave2("another argument", function(){
slave3(1, function(){
slave4(2, slave5);
});
});
});
考虑的内存和CPU使用率方面使用
slave1("some argument",
slave2.bind(null, "another argument",
slave3.bind(null, 1,
slave4.bind(null, 2, slave5)
)
)
);
容易得多,更有效的。 现在,如何与setTimeout的做到这一点:
slave1("some argument",
setTimeout.bind(null, slave2.bind(null, "another argument",
setTimeout.bind(null, slave3.bind(null, 1,
setTimeout.bind(null, slave4.bind(null, 2,
setTimeout.bind(null, slave5, 0)
),0)
),0)
),0)
);
我更详细的 http://morethanslightly.com/index.php/2014/09/executables-the-standard-solution-aka-mind-the-bind/
你使用任何JS库或者它必须是纯JS解释这个问题? – Tomalak 2014-08-27 11:44:20
Pure JS .................... – 2014-08-27 13:49:15