无法理解 javascript 中嵌套事件中的 closures/scope
Trouble understanding closures/scope in nested events in javascript
我正在 angular 中编写应用程序,必须确定图层是否可以加载为 GPX 或 KML(地理数据 XML 文件)。然后我 return 它被成功加载的图层。但是,当我在 .on(ready) 事件(成功事件)中时,我终生无法弄清楚如何将变量设置为 true 。这是我的代码:
(function() {
'use strict';
angular
.module('TractNotes')
.factory('xmldataService', xmldataService);
xmldataService.$inject = [];
/* @ngInject */
function xmldataService() {
var isKML = false;
var isGPX = false;
var service = {
getxmldata: getxmldata
};
return service;
////////////////
function getxmldata(layer) {
var kml = omnivore.gpx('this will fail')
.on('ready', function() {
isKML = true;
})
.on('error', function() {
console.log("This is not a KML layer.")
})
var gpx = omnivore.gpx(layer)
.on('ready', function() {
isGPX = true;
})
.on('error', function() {
console.log("This is not a GPX layer.")
});
if(isKML){
return kml;
}
else if(isGPX){
return gpx;
}
else{
return 'invalid file';
}
// @TODO: use desc xml tag as layer name
}
}
})();
当代码运行时,console.logs 工作正常,但它从来没有 return 任何东西,因为布尔值从未被正确设置。感谢任何帮助理解这一点。
leaflet-omnivore 文档:https://github.com/mapbox/leaflet-omnivore
嗯,这并不容易。当您 运行 您的服务功能时, 'ready' 事件尚未触发,因此 bool 值处于 false 状态。所以他们 return 'invalid file'。我建议将您的服务重构为 return Promise 而不是价值。看看那个 Promise on MDN。然后在 promise 解决后执行你的代码。
更新:
在这里,看一下 jsfiddle
上的示例
function xmlDataService() {
var service = {
getxmlData: getxmlData
};
return service;
function getxmlData(layer) {
return new Promise(
function(resolve, reject) {
console.log('Promise started');
var serviceCreated = false;
var optionsCount = 2;
var optionsFailed = 0;
// First service
window.setTimeout(
function() {
if (!serviceCreated) {
serviceCreated = true;
resolve('First service created');
}
}, Math.random() * 2000 + 1000); // at least a second
// Second Service
window.setTimeout(
function() {
if (!serviceCreated) {
serviceCreated = true;
resolve('Second service created');
}
}, Math.random() * 2000 + 1000);
}
);
}
}
在范围内:
$scope.createService= function() {
$scope.message = "Creating a Service";
var promise = xmlDataService.getxmlData();
promise.then(function(val) {
console.log('Promise resolved');
// Apply result on scope, since it been executed out of scope.
$scope.$apply(function(){
$scope.message = val;
});
});
}
我正在 angular 中编写应用程序,必须确定图层是否可以加载为 GPX 或 KML(地理数据 XML 文件)。然后我 return 它被成功加载的图层。但是,当我在 .on(ready) 事件(成功事件)中时,我终生无法弄清楚如何将变量设置为 true 。这是我的代码:
(function() {
'use strict';
angular
.module('TractNotes')
.factory('xmldataService', xmldataService);
xmldataService.$inject = [];
/* @ngInject */
function xmldataService() {
var isKML = false;
var isGPX = false;
var service = {
getxmldata: getxmldata
};
return service;
////////////////
function getxmldata(layer) {
var kml = omnivore.gpx('this will fail')
.on('ready', function() {
isKML = true;
})
.on('error', function() {
console.log("This is not a KML layer.")
})
var gpx = omnivore.gpx(layer)
.on('ready', function() {
isGPX = true;
})
.on('error', function() {
console.log("This is not a GPX layer.")
});
if(isKML){
return kml;
}
else if(isGPX){
return gpx;
}
else{
return 'invalid file';
}
// @TODO: use desc xml tag as layer name
}
}
})();
当代码运行时,console.logs 工作正常,但它从来没有 return 任何东西,因为布尔值从未被正确设置。感谢任何帮助理解这一点。
leaflet-omnivore 文档:https://github.com/mapbox/leaflet-omnivore
嗯,这并不容易。当您 运行 您的服务功能时, 'ready' 事件尚未触发,因此 bool 值处于 false 状态。所以他们 return 'invalid file'。我建议将您的服务重构为 return Promise 而不是价值。看看那个 Promise on MDN。然后在 promise 解决后执行你的代码。
更新:
在这里,看一下 jsfiddle
上的示例function xmlDataService() {
var service = {
getxmlData: getxmlData
};
return service;
function getxmlData(layer) {
return new Promise(
function(resolve, reject) {
console.log('Promise started');
var serviceCreated = false;
var optionsCount = 2;
var optionsFailed = 0;
// First service
window.setTimeout(
function() {
if (!serviceCreated) {
serviceCreated = true;
resolve('First service created');
}
}, Math.random() * 2000 + 1000); // at least a second
// Second Service
window.setTimeout(
function() {
if (!serviceCreated) {
serviceCreated = true;
resolve('Second service created');
}
}, Math.random() * 2000 + 1000);
}
);
}
}
在范围内:
$scope.createService= function() {
$scope.message = "Creating a Service";
var promise = xmlDataService.getxmlData();
promise.then(function(val) {
console.log('Promise resolved');
// Apply result on scope, since it been executed out of scope.
$scope.$apply(function(){
$scope.message = val;
});
});
}