[英]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.