javascript函数里面的函数变量? (使用异步调用)

时间:2012-02-13 19:37:48

标签: javascript jquery json

我正在使用JIT并创建一个spacetree,但服务器返回的数据格式不正确,所以我认为最简单的方法是构建一个正确格式的字符串,然后用eval(工作正常)。现在的问题是我需要使用另一个不正确格式的JSON字符串来将子节点添加到空间树中,我现在不知道我在做什么。这是我的代码:

function grabdata(empid, fname, lname){
    var json = ''; 
    jQuery.getJSON('../../Mobile_ReportingChain.cfm?Empid='+empid, function(data) {
        console.log(data);
        for(var i=data.DATA.length-1; i>=0; i--){
            json = json + 'id: "' + data.DATA[i][3] + '",name: "' + data.DATA[i][0] + ' ' + data.DATA[i][1] + '",data: {},children: [{';
        }
        json = json + 'id: "' + empid + '",name: "' + fname + ' ' + lname + '",data: {},children: [';
        alert("JSON 1: " + json);
        jQuery.getJSON('../../Mobile_Subordinate.cfm?Empid='+empid, function(data2) { 
            console.log(data2);
            for(var i=0; i<data2.DATA.length; i++){
                json = json + '{id: "' + data2.DATA[i][4] + '",name: "' + data2.DATA[i][0] + ' ' + data2.DATA[i][1] + '",data: {},children: []},';
            }
            alert("JSON 2: " + json);
        });
        json = json + ']';
        for(var i=data.DATA.length; i>0; i--){
            json = json + '}]';
        }
        alert("JSON 3: " + json);
    });
}

以下是我从警报中得到的信息,以及我的目标:

JSON 1: id: "000-25-9687",name: "NAME1          LNAME1                  ",data: {},children: [{id: "000-91-3619",name: "FNAME2            LNAME2                  ",data: {},children: [{id: "000-01-2302",name: "FNAME3            LNAME3                    ",data: {},children: [{id: "000-14-7189",name: "FNAME4           LNAME4                  ",data: {},children: [{id: "000-62-7276",name: "FNAME5 LNAME5",data: {},children: [

JSON 2: id: "000-25-9687",name: "NAME1          LNAME1                  ",data: {},children: [{id: "000-91-3619",name: "FNAME2            LNAME2                  ",data: {},children: [{id: "000-01-2302",name: "FNAME3            LNAME3                    ",data: {},children: [{id: "000-14-7189",name: "FNAME4           LNAME4                  ",data: {},children: [{id: "000-62-7276",name: "FNAME5 LNAME5",data: {},children: []}]}]}]}]{id: "000-21-6506     ",name: "CHILD1          CHILDLNAME1                    ",data: {},children: []},{id: "000-17-7989     ",name: "CHILD2          CHILDLNAME2                   ",data: {},children: []},{id: "000-23-6712     ",name: "CHILD3        CHILDLNAME3              ",data: {},children: []},

JSON 3: id: "000-25-9687",name: "NAME1          LNAME1                  ",data: {},children: [{id: "000-91-3619",name: "FNAME2            LNAME2                  ",data: {},children: [{id: "000-01-2302",name: "FNAME3            LNAME3                    ",data: {},children: [{id: "000-14-7189",name: "FNAME4           LNAME4                  ",data: {},children: [{id: "000-62-7276",name: "FNAME5 LNAME5",data: {},children: []}]}]}]}]

JSON 4: id: "000-25-9687",name: "NAME1          LNAME1                  ",data: {},children: [{id: "000-91-3619",name: "FNAME2            LNAME2                  ",data: {},children: [{id: "000-01-2302",name: "FNAME3            LNAME3                    ",data: {},children: [{id: "000-14-7189",name: "FNAME4           LNAME4                  ",data: {},children: [{id: "000-62-7276",name: "FNAME5 LNAME5",data: {},children: [{id: "000-21-6506     ",name: "CHILD1          CHILDLNAME1                    ",data: {},children: []},{id: "000-17-7989     ",name: "CHILD2          CHILDLNAME2                   ",data: {},children: []},{id: "000-23-6712     ",name: "CHILD3        CHILDLNAME3              ",data: {},children: []},]}]}]}]}]

显然它正在继续前进,并且在它有时间抓取并构建JSON2警报之前做了什么使JSON3警报。如何让它停止并等待getJSON调用完成并且成功函数在它继续之前完成?

2 个答案:

答案 0 :(得分:0)

作为一般规则,如果您正在进行异步调用(例如jQuery.getJSON),那么> 之后脚本中的任何内容都将在之前执行 strong>异步调用完成。

如果你想保持crsytal清晰,你可以这样编写代码:

function grabdata(empid, fname, lname){
    jQuery.getJSON('../../Mobile_ReportingChain.cfm?Empid='+empid, function(data) {
        jQuery.getJSON('../../Mobile_Subordinate.cfm?Empid='+empid, function(data2) { 

            // DO ALL YOUR STUFF WITH data AND data2 HERE

        });
    });
}

这不是最优的,但很明显,两个AJAX调用必须在最内层块中的代码执行之前完成。


如果您正在查看对多个并发ajax请求的更高级处理,则可以创建一个在jQuery.when()完成两个asynce请求时执行的承诺。

以下是一个例子:

$.when(
    $.getJSON('../../Mobile_ReportingChain.cfm?Empid='+empid),
    $.getJSON('../../Mobile_Subordinate.cfm?Empid='+empid)
).done(function (data, data2){

            // DO ALL YOUR STUFF WITH data AND data2 HERE

});

答案 1 :(得分:0)

我在这里是否正确理解你:你需要对服务器进行两次调用

  • Mobile_ReportingChain.cfm?EMPID =
  • Mobile_Subordinate.cfm?EMPID =

这两个电话是相互独立的,不管你是哪一个都没关系 先做两者返回的数据需要处理并组合成一个字符串。您的代码的基本结构是

1 function grabdata(...){
2    // this variable is availabe to all functions
3    var json = ''; 
4    jQuery.getJSON('Mobile_ReportingChain.cfm?Empid='+empid, function(data) {
5        // when data from Mobile_ReportingChain finally arrives: process  and add to var json:
6        json = json + ....
7
8        jQuery.getJSON('Mobile_Subordinate.cfm?Empid='+empid, function(data2) { 
9             // when data from Mobile_Subordinate finally arrives: process  and add to var json:
10            json = json + ....
11       });
12
13        // add some more stuff from Mobile_ReportingChain data to json
14        json = json + '.....
15    });
16 }

这里有两个异步调用,因此实际发生的顺序可能是:

  • 1,2,3,4(异步调用Mobile_ReportingChain),16。完成。功能 返回,var json永远丢失

秒后,来自Mobile_ReportingChain的数据最终到达:

  • 5,6,7,8(异步调用Mobile_Subordinate),13,14。功能 回报。

秒后,当来自Mobile_Subordinate的数据终于到来时:

  • 9,10,函数返回。

这是a jsfiddle,你可以在那里尝试真实。

jQuery提供延迟对象,当+然后处理这种情况时:

function grabdata() {

    $.when($.ajax(url1), $.ajax(url2)).then(

    function(d1, d2) {
        console.log('both calles returned');
        console.log('call 1 returned ' + d1[0].length + ' bytes of data');
        console.log('call 2 returned ' + d2[0].length + ' bytes of data');

        // here is where you do more stuff with the data

    });

    console.log('at the end of grabdata().');
    // nothing intresing to do, nothing to return

}

再次:a jsfiddle尝试一下。