2017-02-27 44 views
0

我有獲取從外部API問題的功能。我需要在數組中至少有5個問題才能運行我的應用程序。檢查返回的JSON的價值和更新,如果假

function getCategoryQuestions(){ 
    var questions = {}; 
    var i = 0; 
    for (i; i < 6; i++){ 
    $.getJSON(makeURL(), function(data){ 
     data = data.category; 
     questions[data.name] = data.questions; 
     validQuestionsLength(questions, data.questions) 
    }) 

    } 
    return questions; 
} 

我運行validQuestionsLength,以檢查是否每個問題陣列在長度爲至少5個元素。

function validQuestionsLength(hash, array){ 
    while (array.length < 5) { 
    $.getJSON(makeURL(), function(data){ 
     data = data.category; 
     hash[data.name] = data.questions 
     array = data.questions; 
    }) 
    console.log(array.length) 
    } 
} 

我想檢查一個數組的長度是否小於5,如果是的話我會從url中獲取一個新的資源。我將把新的值保存到數組中,然後它會檢查這個新值的數組長度。我希望它保持獲取數據,直到條件成立。

發生了什麼事是,一旦validQuestionsLength()方法運行和我有一個數組長度與小於5時,它保持在console.logging無限循環當前陣列。我以爲我在每個循環中保存了一個新的資源。

我不知道在我的邏輯錯誤發生。

我知道有發生如此前的數組變量被複位的console.log可能運行的異步請求。我編輯我的驗證功能,包括做回調執行一次異步完成

function validQuestionsLength(hash, array){ 

    if (array.length < 5) { 
    $.getJSON(makeURL(), function(data){ 
     data = data.category; 
     hash[data.name] = data.questions 

     console.log("data is ", data.questions) 
     array = data.questions; 
    }).done(console.log("array is ", array)) 
    } 
} 

我的目的是向新取的數據保存到數組。但data.questions和數組(它應該指向data.questions的值)是不同的值。 .done()在這種情況下做什麼?

+0

那麼你的電話一次還是N還是一個問題?您是否在查找所有data.name條目中的每個data.name五個或五個總數?現在你擁有數組的方式會被每次調用覆蓋,所以除非你的api調用返回五個項目,否則你將永遠循環。 – Michael

+0

使用'array.push(data.questions)'而不是'array = data.questions;'我不知道你的Json結構,你可能需要在其中添加一些索引,比如'questions [0]'或者其他東西 – Viney

+0

你'重新設置完成回調函數錯誤,您需要將代碼嵌入到lambda函數中,以便成功回調,現在您將console.log的設置結果作爲** done **事件的回調。所以它現在仍然在回調之前執行。 –

回答

0

EDIT2:我做例子,說明你的兩個功能,可以看作爲有效的回調循環,兩者的功能是相似的,所以它可以只是一個功能:

我已經簡化我的劇本和測試,我做了我的testResponse php腳本幾次返回4個元素[「1」,「2」,「3」,「4」]數組,最後返回5個元素[「1」,「2」,「3」,「4」 「5」]數組。

function getCategoryQuestions(callback){ 
    $.getJSON('http://localhost/testResponse.php', function(data){    
     if(data.questions.length < 5){ 
      getCategoryQuestions(callback); 
     } else {      
      callback(data.questions); 
     } 
    }); 
} 

代碼將從URL獲得JSON,如果問題數組是小於5它將再次請求URL,直到將有數組5個或更多的問題。

如果將有數組不會再執行自己5個或更多的問題,它會調用與問題數組作爲參數的回調。

這是你如何使用功能和接收您的問題陣列:

getCategoryQuestions(function(questions){ 
    console.log(questions); 
}); 

還有更多的工作要做,如AJAX錯誤處理。

編輯: getJSON是異步funciton,所以它會在獲取數據後調用它的回調函數,所以即使它沒有被添加到事件隊列中,以後的回調也會被執行。

這是因爲成功的getJSON回調函數的執行被添加到事件隊列,並執行你CONSOLE.LOG陣列後。長度

我做了一個試驗:

<html> 
    <head> 
     <script 
      src="https://code.jquery.com/jquery-2.2.4.min.js" 
      integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" 
      crossorigin="anonymous"></script> 
    </head> 
    <body> 
     <script> 
      $.getJSON('http://localhost/testResponse.php', function(data){ 
       console.log('Callback'); 
      }); 
      console.log('Script end'); 
     </script> 
     Hello! 
    </body> 
</html> 

而結果在控制檯是:

Script end 
Callback 

爲了進一步解釋如何發生我將提供兩個例子 第一示例:

function callCallback(callback){ 
 
\t callback(); 
 
} 
 

 
callCallback(function(){ 
 
\t console.log('Callback'); 
 
}); 
 
console.log('Script end');

會產生:

Callback 
Script end 

,第二個:

function callCallback(callback){ 
 
\t setTimeout(callback, 0); 
 
} 
 

 
callCallback(function(){ 
 
\t console.log('Callback'); 
 
}); 
 
console.log('Script end');

輸出將同我的getJSON例子,所以:

Script end 
Callback 

這是因爲即使thare爲零超時,回調函數被添加到事件隊列,所以它不會立即執行。

編輯:同樣的getJSON是異步功能可按所以它會調用回調函數後,將取回的數據,所以回調以後不會被執行,即使是不添加到事件隊列。