在继续之前等待一个函数完成的正确方法?

我有两个JS函数。 一个叫另一个。 在调用函数中,我想调用另一个,等待该函数完成,然后继续。 所以,例如/伪代码:

function firstFunction(){ for(i=0;i<x;i++){ // do something } }; function secondFunction(){ firstFunction() // now wait for firstFunction to finish... // do something else }; 

我想出了这个解决scheme,但不知道这是否是一个聪明的方法去做。

 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?

处理这种asynchronous工作的一种方法是使用callback函数,例如:

 function firstFunction(_callback){ // do some asynchronous work // and when the asynchronous stuff is complete _callback(); } function secondFunction(){ // call first function and pass in a callback function which // first function runs when it has completed firstFunction(function() { console.log('huzzah, I\'m done!'); }); } 

根据@Janaka Pushpakumara的build议,你现在可以使用箭头函数来实现同样的事情。 例如:

firstFunction(() => console.log('huzzah, I\'m done!'))

看起来你错过了一个重要的观点: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循环中“产生”( // do something ),循环可能不会被打断并且必须首先完成(更多细节: Javascript线程处理和竞争条件 )。

也就是说,您仍然可以使firstFunction内的代码stream成为asynchronous,并使用callback或承诺来通知调用者。 你必须放弃循环,并用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代码stream中“打”asynchronous空洞( 更多细节和示例 )。 但是,浏览器对生成器的支持目前仅限于Firefox和Chrome,AFAIK。