Javascript 从JS函数返回

Javascript 从JS函数返回,javascript,dojo,esri,Javascript,Dojo,Esri,基本JS问题,请对我放松点我是新手:) 我将2个变量传递给findRelatedRecords函数,该函数查询其他相关表并组装一个称为数据的对象数组。因为findRelatedRecords有很多内部函数,所以我很难从函数中取出数据数组 目前,我在findRelatedRecords中调用showWin,但我想更改它,以便可以直接从findRelatedRecords中获取数据数组,而不是跳转到showWin function findRelatedRecords(features,evtObj

基本JS问题,请对我放松点我是新手:)

我将2个变量传递给findRelatedRecords函数,该函数查询其他相关表并组装一个称为数据的对象数组。因为findRelatedRecords有很多内部函数,所以我很难从函数中取出数据数组

目前,我在findRelatedRecords中调用showWin,但我想更改它,以便可以直接从findRelatedRecords中获取数据数组,而不是跳转到showWin

function findRelatedRecords(features,evtObj){
    //first relationship query to find related branches

    var selFeat = features
    var featObjId = selFeat[0].attributes.OBJECTID_1        
    var relatedBranch = new esri.tasks.RelationshipQuery();
    relatedBranch.outFields = ["*"];
    relatedBranch.relationshipId = 1; //fac -to- Branch
    relatedBranch.objectIds = [featObjId];
        facSel.queryRelatedFeatures(relatedBranch, function(relatedBranches) {
        var branchFound = false;
        if(relatedBranches.hasOwnProperty(featObjId) == true){
            branchFound = true;
            var branchSet = relatedBranches[featObjId]
            var cmdBranch = dojo.map(branchSet.features, function(feature){
                return feature.attributes;
            })
        }

        //regardless of whether a branch is found or not, we have to run the cmdMain relationship query
        //the parent is still fac, no advantage of the parent being branch since cmcMain query has to be run regardless
        //fac - branch - cmdMain - cmdSub <--sometimes
        //fac - cmdMain - cmdSub <-- sometimes

        //second relationship query to find related cmdMains            
        var relatedQuery = new esri.tasks.RelationshipQuery();
        relatedQuery.outFields = ["*"];
        relatedQuery.relationshipId = 0; //fac -to- cmdMain
        relatedQuery.objectIds = [featObjId];
        //rather then listen for "OnSelectionComplete" we are using the queryRelatedFeatures callback function
        facSel.queryRelatedFeatures(relatedQuery, function(relatedRecords) {
            var data = []           
            //if any cmdMain records were found, relatedRecords object will have a property = to the OBJECTID of the clicked feature
            //i.e. if cmdMain records are found, true will be returned; and continue with finding cmdSub records
            if(relatedRecords.hasOwnProperty(featObjId) == true){
                var fset = relatedRecords[featObjId]
                var cmdMain = dojo.map(fset.features, function(feature) {
                    return feature.attributes;
                })
                //we need to fill an array with the objectids of the returned cmdMain records
                //the length of this list == total number of mainCmd records returned for the clicked facility
                objs = []
                for (var k in cmdMain){
                    var o = cmdMain[k];
                    objs.push(o.OBJECTID)                       
                }

                //third relationship query to find records related to cmdMain (cmdSub)
                var subQuery = new esri.tasks.RelationshipQuery();
                subQuery.outFields = ["*"];
                subQuery.relationshipId = 2;
                subQuery.objectIds = [objs]
                subTbl.queryRelatedFeatures(subQuery, function (subRecords){

                    //subRecords is an object where each property is the objectid of a cmdMain record
                    //if a cmdRecord objectid is present in subRecords property, cmdMain has sub records
                    //we no longer need these objectids, so we'll remove them and put the array into cmdsub
                    var cmdSub = []
                    for (id in subRecords){
                        dojo.forEach(subRecords[id].features, function(rec){
                            cmdSub.push(rec.attributes)
                        })
                    }
                    var j = cmdSub.length;
                    var p;
                    var sub_key;
                    var obj;
                    if (branchFound == true){
                        var p1 = "branch";
                        obj1 = {};
                        obj1[p1] = [cmdBranch[0].Branches]
                        data.push(obj1)
                    }                        
                    for (var i=0, iLen = cmdMain.length; i<iLen; i++) {
                        p = cmdMain[i].ASGMT_Name
                        obj = {};
                        obj[p] = [];
                        sub_key = cmdMain[i].sub_key;
                        for (var j=0, jLen=cmdSub.length; j<jLen; j++) {
                            if (cmdSub[j].sub_key == sub_key) {
                                obj[p].push(cmdSub[j].Long_Name);
                            }
                        }
                        data.push(obj);
                    }
                    showWin(data,evtObj) <---this would go away
                })
            }
            //no returned cmdRecords; cmdData not available
            else{
                p = "No Data Available"
                obj = {}
                obj[p] = []
                data.push(obj)
            }
            showWin(data,evtObj) <--this would go away
        })
    })
}
这可能吗

谢谢

编辑

再解释一下

我将对象事件侦听器连接到如下函数:

function b (input){
    dojo.connect(obj, "onQueryRelatedFeaturesComplete", getData);
    obj.queryRelatedFeatures(input);
    console.log(arr) //<----this doesn't work
}

function getData(relatedFeatData){
    var arr = [];
    //populate arr
    return arr;
}
功能b(输入){
connect(obj,“onQueryRelatedFeaturesComplete”,getData);
对象查询相关特征(输入);

console.log(arr)//编辑后更新:

由于此事件的连接方式,您不能简单地从中返回数据。返回将让Dojo调用连接到
onSelectionComplete
的下一个方法

init
运行时,井的
onSelectionComplete
事件将执行/触发
findRelatedRecords
很久,这就是为什么您会看到
未定义的
/
null
值。使用此类系统的唯一方法是1)调用一个类似您已经调用的方法执行或2)触发自定义事件/消息(从技术上讲,它仍然只是调用一个方法)

如果要使此方法更易于使用,应重构/提取其片段,使其成为一个较小的函数,但包含在许多函数中。此外,将其更改为在
findRelatedRecords
方法的末尾只有一个退出点将有所帮助。
subbl.queryRelatedFeatures()中定义的函数
将是一个很好的起点

很抱歉,在这种情况下,Dojo提供给您的有点限制

预编辑答案:

只要从中返回您的数据。任何有showWin呼叫的地方都可以使用此返回

  return {
    data: data,
    evtObj: evtObj
  }
那么你的新功能会是这样的

function newfunct(){
    var newData = findRelatedRecords(feature,evt);
    console.log(newData);
    console.log(newData.data);
    console.log(newData.evtObj);
}
如果您只需要该“数据”对象,则将返回更改为仅返回数据;


另外,开始使用分号终止语句。

我是否遗漏了什么,或者您是否只需要添加
返回数据;
showWin将在哪里?console.log(newData)您是否到处返回对象?在B()中上面是如何定义的?你能把一个JSFIDLE放在一起吗?中间有一个叫做******impt section的部分解释了我的问题谢谢!!哦,现在你的编辑更有意义了。我会为你更新我的答案。
function newfunct(){
    var newData = findRelatedRecords(feature,evt);
    console.log(newData);
    console.log(newData.data);
    console.log(newData.evtObj);
}