簡體   English   中英

需要幫助來創建帶有回調的異步函數

[英]Need help creating async function with callback

我有一個JSON對象,其中包含一些條目(約會),每個條目都有一個“位置ID”。 然后,我遍歷這些條目並通過socketIO向我的nodeJS服務器發出請求,以從具有位置ID的文檔中獲取數據。

最后,我需要一個包含經度/經度數據的數組,以便在地圖上創建一些標記。

這是代碼:

//controller for showing map
.controller('MapCtrl', function($scope, socket){

    socket.emit('getApp', staticUserid);

        socket.on('getApps', function (appdata) {
                var locArr = [];
                for (var i = 0; i < appdata.length; i++) {
                    if (appdata[i].locationid != '') {
                        locArr.push(appdata[i].locationid);
                    }
                }
                var LatLngArr = [];
                for (var j = 0; j < locArr.length; j++) {
                    socket.emit('getLocation', locArr[j]);
                    socket.on('getLoc', function (locData) {
                        console.log('received lat/lng: ' + locData.lat + '/' + locData.lng);
                        if (!LatLngArr[j]) LatLngArr[j] = []
                        LatLngArr[j][0] = locData.lat;
                        LatLngArr[j][1] = locData.lng;
                    });
                }
                //console.log('test:'+LatLngArr[0][0]);
        });

    var newMarkers = [[52.549678, 13.3879516],[52.5442992, 13.352809],[52.5186283,13.3761181]]; // this should be the generated array
    var newCenter = [52.549678, 13.3879516];
    createMap(newCenter,newMarkers);

})

問題是,var LatLngArr不是在...之外定義的。

socket.on('getLoc', function (locData)

如果有人可以幫助我,那將非常好:-)

非常感謝!

如果可以使用Promises

.controller('MapCtrl', function($scope, socket){

    socket.emit('getApp', staticUserid);

    socket.on('getApps', function (appdata) {
        var locArr = [];
        for (var i = 0; i < appdata.length; i++) {
            if (appdata[i].locationid != '') {
                locArr.push(appdata[i].locationid);
            }
        }
        var LatLngArr = [];
        var promises = [];
        for (var j = 0; j < locArr.length; j++) {
            promises[j] = (function(captured_j) {
                return new Promise(function(resolve, reject) {
                    socket.emit('getLocation', locArr[captured_j]);
                    socket.on('getLoc', function (locData) {
                        console.log('received lat/lng: ' + locData.lat + '/' + locData.lng);
                        if (!LatLngArr[captured_j]) LatLngArr[captured_j] = []
                        LatLngArr[captured_j][0] = locData.lat;
                        LatLngArr[captured_j][1] = locData.lng;
                        resolve({index: captured_j, result: LatLngArr[captured_j]});
                    });
                });
            }(j));
        }
        Promise.all(promises).then(function(arr) {
            // ******************************************
            // ******************************************
            // arr is an array of {index: #, result [lat, lng]} - but you can also use LatLngArr
            // ******************************************
            // ******************************************
        });
    });
    var newMarkers = [[52.549678, 13.3879516],[52.5442992, 13.352809],[52.5186283,13.3761181]]; // this should be the generated array
    var newCenter = [52.549678, 13.3879516];
    createMap(newCenter,newMarkers);
})

嘗試這個

for (var j = 0; j < locArr.length; j++) {
    (function(captured_j) {
        socket.emit('getLocation', locArr[captured_j]);
        socket.on('getLoc', function (locData) {
            console.log('received lat/lng: ' + locData.lat + '/' + locData.lng);
            if (!LatLngArr[captured_j]) LatLngArr[captured_j] = []
            LatLngArr[captured_j][0] = locData.lat;
            LatLngArr[captured_j][1] = locData.lng;
            //
            // the required result
            //
            if (j === 0) {
                console.log('test:'+LatLngArr[0][0]);
            }
            //
        });
    }(j));
}

您的代碼失敗的原因是由於該行的異步特性:

socket.on('getLoc', function (locData)

因此, LatLngArr實際上是在注冊回調時定義的,但在調用回調時不再存在。 這樣做的原因是JavaScript使用Closures

您可能會看到以下線程: JavaScript閉包如何工作?

因此,您必須將其包裝在IIFE中 這樣,函數將立即執行,以使j的值符合您的預期,因為它不再引用外部作用域的j

編輯:在David Hermann的“ Effective Javascript”(有效Javascript)第13條中可以找到一個很好的解釋,我完全可以推薦這本書。 如果您在理解它時遇到問題,那么查看此線程可能會有所幫助。

暫無
暫無

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

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