2015-07-10 35 views
-1

我想在JavaScript + Ajax做一個小網站,我想遞歸做它。我從來沒有使用Ajax,問題是我不知道完成功能。該代碼看起來像這樣:在javascript和ajax遞歸函數

var cont = 0; 
var function1 = function (query) { 
    $.ajax({ 
     url: '...', 
     data: { 
       . 
       . 
       . 
     }, 
     success: function (response) { 
      instructions; 
      function2(param1, param2); 
     } 
    }); 
}; 
var function2 = function (query, param2) { 
    $.ajax({ 
     url: '...', 
     data: { 
       . 
       . 
       . 
     }, 
     success: function (response) { 
      instructions; 
      function3(param1, param2, param3); 
     } 
    }); 
}; 
var function3 = function (query, param2, param3) { 
    if (cont == 2) { 
     console.log("finish"); 
     return; 
    } 
    var test = $.ajax({ 
     url: '...', 
     data: { 
       . 
       . 
       . 
     }, 
     success: function (response) { 
      if (...) { 
       cont++; 
       instructions; 
       var audio = new Audio(...); 
       audio.play(); 
       audio.onended = function() { 
        instructions; 
        function3(query, param2, param3); 
        return; 
       }; 
      } else { 
       instructions; 
       function3(query, param2, param3); 
      }; 
      return; 
     } 
    }); 
    return; 
}; 
document.getElementById('search-form').addEventListener('submit', function (e) { 
    e.preventDefault(); 
    function1(document.getElementById('query').value); 
}, false); 

所以基本上,當cont == 2我試圖擺脫的JavaScript function3return;但是程序的某些部分(我不知道,如果success: function (response)或完整的JavaScript function3)是仍在運行並正在執行指令。

我該如何解決這個問題?

+0

如果您if條件未通過作爲真正的三倍,'cont'永遠不會'2'。 –

+0

'paramX'值來自哪裏?你可以把它們全部放在一個數組中,並遞歸地將它們傳遞給一個函數。 –

+0

它總是達到2,那不是問題 –

回答

0

首先,正確的做法是利用jQuery的延遲對象。

正如您可能已經注意到的,程序不會簡單地等待ajax請求,然後進入'成功'處理程序。這是因爲Javascript使用非阻塞/等待模型。所以你調用$ .ajax({params,...}),這會發送請求,但之後的任何內容都會立即運行,而不用等待。然後,一旦頂層函數完成執行並且沒有別的運行,就可以處理響應,並調用「成功」處理程序。

那麼如何正確地做到這一點?通過安排你的請求函數像這樣開始:

function doRequest1() { 
    return $.ajax({ 
     url: '...', 
     data: { 
       . 
       . 
       . 
     } 
    }); 
} 

function doRequest2(parameter) { 
    return $.ajax({ 
     url: '...', 
     data: { 
       . 
       p: parameter 
       . 
     } 
    }); 
} 

請注意,我們不提供成功處理程序,但我們正在返回的值是$就返回。這是一個延遲對象,用於表示已發送但未收到/處理響應的請求。你可以附加一個處理程序到這樣的對象:

var r1 = doRequest1(); 

r1.then(function() { 
    // Do stuff on success... 
}); 

這些對象的一個​​好處是,他們可以用'然後'鏈接。 「然後」接受一個函數,它接受舊請求的值,併產生一個新的請求下一步:

var allRequests = doRequest1().then(function(result1) { 
    return doRequest2("hello"); 
}); 

現在的「allRequests」變量是表示doRequest2的結果的延遲對象。你如何得到這個結果?您可以使用「那麼()」,就像任何其他的延遲:

allRequests.then(function(result) { 
    alert("All requests completed. Result of last one: " + result); 
}); 

確保您瞭解如何從1所請求的結果可以用來設置參數爲下一個,甚至可以決定哪些要求下一步。

如果你不需要一個請求的結果來確定下一個,而你只是想運行多個請求,並等待他們全部完成,你可以使用一個快捷方式,「當」:

$.when(doRequest1(),doRequest2(), doRequest3()).then(function(result1,result2,result3) { 
    // All done 
}); 

約deferreds的另一個好處是,它們可以被取消:

allRequests.abort(); 

使用上面,希望你可以看到如何調整你的代碼,所以你得到請求序列與功能,畢竟運行3已完成。

-1

通過程序流量觀察全局變量cont的值。當調用function3()時,它可能永遠不會等於2,這就是您的程序繼續運行的原因。

+0

它總是達到2,那不是問題 –