How can I return the value of a deferred method in javascript

◇◆丶佛笑我妖孽 提交于 2020-01-17 05:09:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!