我有两个JS函数。一个打电话给另一个。在调用函数中,我想调用另一个函数,等待该函数完成,然后继续。因此,例如/伪代码:
function firstFunction(){
for(i=0;i<x;i++){
// do something
}
};
function secondFunction(){
firstFunction()
// now wait for firstFunction to finish...
// do something else
};
我想出了这个解决方案,但不知道这是否是一个聪明的方法。
var isPaused = false;
function firstFunction(){
isPaused = true;
for(i=0;i<x;i++){
// do something
}
isPaused = false;
};
function secondFunction(){
firstFunction()
function waitForIt(){
if (isPaused) {
setTimeout(function(){waitForIt()},100);
} else {
// go do that thing
};
}
};
这合法吗?有没有更优雅的处理方式?也许是用jQuery?
这里您似乎忽略了重要的一点:JavaScript是一个单线程执行环境。让我们再看一遍你的代码,注意我添加了alert(“Here”):
var isPaused = false;
function firstFunction(){
isPaused = true;
for(i=0;i<x;i++){
// do something
}
isPaused = false;
};
function secondFunction(){
firstFunction()
alert("Here");
function waitForIt(){
if (isPaused) {
setTimeout(function(){waitForIt()},100);
} else {
// go do that thing
};
}
};
你不需要等待isPaused。当你看到“Here”警告时,isPaused将为false, firstFunction将返回。这是因为你不能从for循环内部“屈服”(//做某事),循环可能不会被中断,必须先完全完成(更多细节:Javascript线程处理和竞争条件)。
也就是说,您仍然可以使firstFunction内部的代码流是异步的,并使用回调或承诺通知调用方。你必须放弃for循环,用if (JSFiddle)来模拟它:
function firstFunction()
{
var deferred = $.Deferred();
var i = 0;
var nextStep = function() {
if (i<10) {
// Do something
printOutput("Step: " + i);
i++;
setTimeout(nextStep, 500);
}
else {
deferred.resolve(i);
}
}
nextStep();
return deferred.promise();
}
function secondFunction()
{
var promise = firstFunction();
promise.then(function(result) {
printOutput("Result: " + result);
});
}
另一方面,JavaScript 1.7引入了yield关键字作为生成器的一部分。这将允许在同步JavaScript代码流中“打孔”异步(更多细节和示例)。然而,浏览器对生成器的支持目前仅限于Firefox和Chrome, AFAIK。
试试这个
function firstFunction(){
// do something
X=true;
return X;
}
function secondFunction(){
X=false;
X=firstFunction();
setTimeout( function() {
if(X==true){
// do something else
}else{
// do something else
}
alert(X); // To check X
}, 100); // Can increase time delay 200,300, ...
}
将时间从100增加到200,300,…基于firstFunction完成所需的时间