问题
I am trying to write a module which projects coordinates into a new Spatial Reference, but the javascript syntax has beaten me once again.
This is how the module currently looks like:
define(["esri/geometry/Point", ...],
function(Point, SpatialReference, ...){
var gmsvc = new GeometryService("http://server/maps/rest/services/Utilities/Geometry/GeometryServer");
/*...*/
return {
/*...*/
//transforms the current point on the map to the new wkid
transformCoordinates: function(point, newWkId) {
var param = new ProjectParameters();
var newPoint;
param.geometries = [point];
param.outSR = new SpatialReference({ wkid: newWkId});
gmsvc.project(param);
gmsvc.on('project-complete', function(result) {
newPoint = result.geometries[0];
});
return newPoint;
}
};
});
As per the documentation GeometryService.project(parameter)
is marked as deferred, so I try to access the result of it in the OnProjectComplete event. At this point result.geometries[0]
is a valid Point with an x, y and SpatialReference property.
Assigning this to the newPoint
variable and returning it, results in an undefined
being returned:
console.log(CoordinateTransUtils.transformCoordinates(evt.mapPoint, 5254));
> undefined
Changing the code to
return gmsvc.on('project-complete', function(result) {
return result.geometries[0];
});
results in a return value of:
Object {id: 216, receiveArguments: true, previous: Object}advice: (){var b,c={},e=arguments.length;for(b=0;b<e;b++)c[f[b]]=arguments[b];c.target||(c.target=d);a.call(d,c)}id: 216next: Objectprevious: ObjectreceiveArguments: trueremove: (){if(h.advice){var c=h.previous,d=h.next;!d&&!c?delete b[e]:(c?c.next=d:b[e]=d,d&&(d.previous=c));b=a=h.advice=null}}__proto__: Object
which isn't a point either.
My question therefore is, how to return the point stored in result.geometries[0]
with an explanation what I am doing wrong here.
回答1:
In your example, newPoint
will only actually set after the return
statement is already processed, so it's undefined when that line runs.
Generally, if something within your function's logic is asynchronous, your function in itself will need to be asynchronous in nature as well. Typically in these cases it is recommended to return a promise. e.g.:
transformCoordinates: function(point, newWkId) {
var dfd = new Deferred(); // (from dojo/Deferred)
var param = new ProjectParameters();
param.geometries = [point];
param.outSR = new SpatialReference({ wkid: newWkId});
gmsvc.project(param);
gmsvc.on('project-complete', function(result) {
dfd.resolve(result.geometries[0]);
});
// If there is an accompanying error event, you should also
// listen to that and call dfd.reject in its handler.
return dfd.promise;
}
See the Deferred and Promise tutorials for more information.
来源:https://stackoverflow.com/questions/30803565/how-can-i-return-the-value-of-a-deferred-method-in-javascript