簡體   English   中英

Javascript異步功能:回調不起作用

[英]Javascript asynchronous function: callback not working

我正在嘗試從Javascript中的異步函數返回結果。

我已經看到了這個問題: 如何從異步調用返回響應? ,而我正在嘗試實現回調解決方案,但是出了點問題。

這是我的代碼:

function getLocation(callback){
    var lat;
    var long;
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position)
                {
                    lat = position.coords.latitude;
                    long = position.coords.longitude;
                }, function()
                {
                    console.log('Please enable geolocation in your browser.');
                });
    } else {
        alert('It seems like geolocation is not enabled in your browser.');
    }
var res = {
        "lat": lat,
        "long": long
};
callback(res);
}

function getEventNearYou(){
    var list = [];
    getLocation(function(obj){
        var lat = obj.lat;
        var long = obj.long;
        $.ajax({
                url : 'http://www.skiddle.com/api/v1/events/search/?api_key=myapikey' + '&latitude=' + lat + '&longitude=' + long + '&radius=800&eventcode=LIVE&order=distance&description=1',
                type : "GET",
                async : false,
                success : function(response) {
                        $(response).find("results").each(function() {
                        var el = $(this);
                        var obj = {
                                    "eventname" : el.find("eventname").text(),
                                    "imageurl" : el.find("imageurl").text(),
                                  }
                        list.push(obj);
                        });
                        } 
                });
        return list;
    });
}

基本上,我想找到我的當前位置,並向www.skiddle.com創建HTTP get請求以檢索該位置附近的事件。

這就是我所謂的函​​數:

var x = getEventNearYou();

但是我似乎犯了一個錯誤,因為我遇到了錯誤的請求錯誤(未定義latlong )。

您使用回調的方式會削弱其用途。 您仍在以同步樣式編寫代碼。 您應該繼續參考: 如何從異步調用返回響應?

同時,我將重組您的代碼以顯示其完成方式。

  1. 根據經驗,如果函數內的任何代碼使用回調,則該外部函數也需要接受回調作為參數。

  2. 如果在回調函數中為變量賦值,則不會在回調函數之外定義該變量(因為異步代碼始終同步代碼之后運行)。

  3. 不要使用async: false

function getLocation(callback){
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (position) {
            var lat = position.coords.latitude;
            var long = position.coords.longitude;
            var res = { "lat": lat, "long": long }; 
            callback(res);
        }, function() {
            console.log('Please enable geolocation in your browser.');
        });
    } else {
        alert('It seems like geolocation is not enabled in your browser.');
    }
}

function getEventNearYou(callback) {
    getLocation(function(pos){
        var lat = pos.lat;
        var long = pos.long;
        $.ajax({
            url: 'http://www.skiddle.com/api/v1/events/search/?api_key=myapikey' + '&latitude=' + lat + '&longitude=' + long + '&radius=800&eventcode=LIVE&order=distance&description=1',
            type: "GET",
            success: function(response) {
                var list = [];
                $(response).find("results").each(function() {
                    var el = $(this);
                    var obj = {
                        "eventname": el.find("eventname").text(),
                        "imageurl" : el.find("imageurl").text(),
                    };
                    list.push(obj);
                });
                callback(list);
            } 
        });
    });
}

然后使用回調函數調用getEventNearYou

getEventNearYou(function (events) {
    // code which relies on `events` can be called from here
});

只是在4castle的出色答案中添加了更多解釋。 在您編寫的代碼中,用Javascript調用getLocation()函數時,將發生以下情況:

  1. var latvar longundefined值實例化。
  2. 調用navigator.geolocation.getCurrentPosition()會花費很長時間。
  3. 同時,Javascript尋找其他事情要做,並移至函數的下一行。
  4. 使用當前未定義latlong實例化res對象。 也就是說, res是: { "lat": undefined, "long": undefined }
  5. callback函數在res上調用。 這意味着使用latlong未定義值callback
  6. navigator.geolocation.getCurrentPosition()最終完成了所要做的工作,並將值分配給latlong ,但是現在為時已晚,因為您的回調函數已經在未定義的值上調用了。

在4castle的修改后的代碼中,步驟4-5被放置在navigator.geolocation.getCurrentPosition()的匿名回調函數中,這意味着直到getCurrentPosition()完成獲取位置后,這些行才會執行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM