2016-12-29 12 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

なぜ約束を使用しないのですか?そうすれば、それは本当に非同期になります。 – Baruch

+0

@Baruch:これは本当に非同期です。 –

+0

フローを処理するコールバックとして関数をチェーンする必要があります – Aethyn

答えて

2

XMLHttpRequestオブジェクトを1つ再利用しています。しないでください。要求ごとに新しいものを(***行を参照)を作成します。

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で追加されたイベントリスナーが1つあります。
次に、function3に追加のイベントリスナーを追加します。
そして、関数4​​の別のイベントリスナー。

考えられる解決策:
1.異なるXHRオブジェクト毎時間:fn1XHR = new XMLHttpRequest()など。それ以外は

が、私は約束を使用すると、あなたがしているシナリオのためのより良いパターンでできると思いますここで説明する。

関連する問題