2016-12-29 132 views
2

我試圖簡化代碼,但是在這裏我向api發出請求,它一切正常,直到我嘗試調用函數4中的函數5,它將接收到的數據由api轉換爲function2。JavaScript函數調用順序不正確

有沒有人知道如何阻止這種情況發生?

var xhr = new XMLHttpRequest(); 
var counter = 0; 

window.onload = function() { 
    var add_button = document.getElementById('add_button'); 
    add_button.addEventListener('click', function1); 


var function1 = function() { 
    counter++; 
    xhr.addEventListener('load', function2); 
    var url = 'https://api.example.org/search'; 
    console.log(url); 
    xhr.open("GET", url); 
    xhr.send(); 
}; 

var function2 = function() { 
    var data = JSON.parse(this.response); 
    console.log(data); 
    function3(); 
}; 

var function3 = function() { 
    for (var i in searchArray) { 
     var Url2 = 'https://api.example.org/search2'; 
     xhr.open("GET", Url2); 
     xhr.addEventListener('load', function4); 
     xhr.send(); 
    }; 
}; 

var function4 = function() { 
    var data2 = JSON.parse(this.response); 
    if (counter === 3) { 
     var url3 = 'https://api.example.org/search3'; 
     xhr.open("GET", url3); 
     xhr.addEventListener('load', function5); 
     xhr.send(); 
    }; 
}; 

var function5 = function() { 
    var data3 = JSON.parse(this.response); 
}; 
+1

爲什麼不使用Promise?這樣它就會真正異步。 – Baruch

+0

@Baruch:它已經是真正的異步了。 –

+0

您需要鏈接函數作爲回調來處理流程 – Aethyn

回答

2

您正在重複使用單個XMLHttpRequest對象。別。爲每個請求創建一個新的(見***線):

var counter = 0; 

window.onload = function() { 
    var add_button = document.getElementById('add_button'); 
    add_button.addEventListener('click', function1); 


var function1 = function() { 
    counter++; 
    var xhr = new XMLHttpRequest();     // *** 
    xhr.addEventListener('load', function2); 
    var url = 'https://api.example.org/search'; 
    console.log(url); 
    xhr.open("GET", url); 
    xhr.send(); 
}; 

var function2 = function() { 
    var data = JSON.parse(this.response); 
    console.log(data); 
    function3(); 
}; 

var function3 = function() { 
    for (var i in searchArray) { 
     var Url2 = 'https://api.example.org/search2'; 
     var xhr = new XMLHttpRequest();    // *** 
     xhr.open("GET", Url2); 
     xhr.addEventListener('load', function4); 
     xhr.send(); 
    }; 
}; 

var function4 = function() { 
    var data2 = JSON.parse(this.response); 
    if (counter === 3) { 
     var url3 = 'https://api.example.org/search3'; 
     var xhr = new XMLHttpRequest();    // *** 
     xhr.open("GET", url3); 
     xhr.addEventListener('load', function5); 
     xhr.send(); 
    }; 
}; 

var function5 = function() { 
    var data3 = JSON.parse(this.response); 
}; 

還要注意的是function3創建幾個重疊的請求(假設循環是有原因的循環),所以只是提防這一點。


for (var i in searchArray) { 

是可疑。您沒有顯示searchArray,但如果它確實是陣列for-in通常不是通過它循環的最佳方式。詳情請參閱For-each over an array in JavaScript?

+0

謝謝,這個工作完美,並找到function3中的問題! – Jess

+2

'不要' - 一個真正簡潔而全能的句子 –

1

您看到的主要問題來自嘗試重用相同的XHR對象。

此XHR對象已經在function1中添加了一個事件偵聽器。
接下來,在函數3中添加一個附加的事件偵聽器。
然後在函數4中的另一個事件監聽器。

可能的解決辦法:
1.使用每次不同的XHR對象:fn1XHR = new XMLHttpRequest()等。

除此之外,我覺得用一個承諾可以爲你的方案更好的模式在這裏描述。