2016-03-01 87 views
0

我正在從api加載數據,我需要在加載代碼後運行一個函數。如何異步運行函數(XMLHttpRequest)

function make(query, callback){ 
    console.log("1"); 
    var results = makeRequest(query); 
    return callback(results); 
}; 

setPoints = function(results){ 
    console.log("2"); 
    for(var key in results) 
    { 
     console.log("3"); 
     var myLatLng = {lat: key.lat, lng: key.lon}; 
     var marker = new google.maps.Marker({ 
      position: myLatLng, 
      map: map, 
      title: 'Hello World!' 
     }); 
    } 
}; 

make(3, setPoints); 

makeRequest = function(place) { 
    var req = new XMLHttpRequest(); 
    req.open('GET', "https://trailapi-trailapi.p.mashape.com/?limit=25&q[city_cont]=San+Luis+Obispo&radius=205", true); 
    req.setRequestHeader('X-Mashape-Key', 'JwTKoEqkTbmsh3eqT0fBweCHYIAUp1h1GCbjsnkh59Bok0iqOC'); 
    req.onreadystatechange = function() { 
     if (req.readyState === 4) { 
      if (req.status >= 200 && req.status < 400) { 
       var response = JSON.parse(req.responseText); 
       var latLongs = response.places.map(function (key) { 
        return {lat: key.lat, lon: key.lon}; 
       }); 
       console.log("Returned"); 
       return latLongs; 
      } else { 
       alert("Failed to load " + req.status); 
       return null; 
      } 
     } 
    }; 
    req.send(); 
} 

我想代碼記錄「1,返回,2,3」。相反,它正在記錄「1,2,返回」。

+0

我的意思是,你可以在['setTimeout'(https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout)調用包裹。雖然你故意這樣做,但似乎有點奇怪。 –

+3

您需要將該回調作爲參數傳遞給'makeRequest'(這是實際的異步函數),您可以從'readystatechange'回調*調用它,而不是返回結果。 – Bergi

回答

2

解決方法是將回調傳遞給函數makeRequest。此回調在XMLHttpRequest完成後運行。

function make(query, callback){ 
    console.log("1"); 
    makeRequest(query,callback); 

}; 

setPoints = function(results){ 
    console.log("2"); 
    for(var key in results) 
    { 
     console.log("3"); 
     var myLatLng = {lat: key.lat, lng: key.lon}; 
     var marker = new google.maps.Marker({ 
      position: myLatLng, 
      map: map, 
      title: 'Hello World!' 
     }); 
    } 
}; 

make(3, setPoints); 
makeRequest = function(place, callback) { 
    var req = new XMLHttpRequest(); 
    req.open('GET', "https://trailapi-trailapi.p.mashape.com/?limit=25&q[city_cont]=San+Luis+Obispo&radius=205", true); 
    req.setRequestHeader('X-Mashape-Key', 'JwTKoEqkTbmsh3eqT0fBweCHYIAUp1h1GCbjsnkh59Bok0iqOC'); 
    req.onreadystatechange = function() { 
     if (req.readyState === 4) { 
      if (req.status >= 200 && req.status < 400) { 
       var response = JSON.parse(req.responseText); 
       var latLongs = response.places.map(function (key) { 
        return {lat: key.lat, lon: key.lon}; 
       }); 
       console.log("Returned"); 
       return callback(latLongs); 
      } else { 
       alert("Failed to load " + req.status); 
       return null; 
      } 
     } 
    }; 
    req.send(); 
} 

另一個可怕的解決方案在你的問題是做功能makeRequest同步。

在方法XMLHttpRequest.open中,您可以在第三個參數中定義AJAX a/synchronous函數(只應將值true更改爲false)。

makeRequest = function(place) { 
    var req = new XMLHttpRequest(); 
    req.open('GET', "https://trailapi-trailapi.p.mashape.com/?limit=25&q[city_cont]=San+Luis+Obispo&radius=205", false); 
    req.setRequestHeader('X-Mashape-Key', 'JwTKoEqkTbmsh3eqT0fBweCHYIAUp1h1GCbjsnkh59Bok0iqOC'); 
    req.onreadystatechange = function() { 
     if (req.readyState === 4) { 
      if (req.status >= 200 && req.status < 400) { 
       var response = JSON.parse(req.responseText); 
       var latLongs = response.places.map(function (key) { 
        return {lat: key.lat, lon: key.lon}; 
       }); 
       console.log("Returned"); 
       return latLongs; 
      } else { 
       alert("Failed to load " + req.status); 
       return null; 
      } 
     } 
    }; 
    req.send(); 
} 
+0

一個簡單而簡單的可怕解決方案。 – Bergi

+0

是的,它是可怕的解決方案,但在他的問題中獲得了預期的結果。你會解釋回調之間的不同,並結束函數或同步函數。謝謝 :)。 – caballerog

+0

OP已經試圖使用回調,他只錯過了一步。這個解決方案是不恰當的。 – Bergi