javascript中函数内部的变量?(使用异步调用)

Variables inside functions inside functions in javascript? (with async calls)

本文关键字:异步 调用 函数 内部 变量 javascript      更新时间:2023-09-26

我正在使用JIT并创建一个空间树,但服务器返回的数据格式不正确,所以我认为最简单的方法是构建一个正确格式的字符串,然后用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调用完成,成功函数完成后再继续?

一般来说,如果您正在进行异步调用(如jQuery.getJSON),则在该调用之后的脚本中的任何内容都将在异步调用完成之前执行。

如果你想保持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请求进行更高级的处理,那么可以创建一个promise,该promise在使用jQuery.when()完成两个异步请求时执行。

这里有一个例子:

$.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
});

我对你的理解正确吗:你需要对服务器进行两次调用

  • Mobile_PortingChain.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_PortingChain的异步调用)、16。完成。作用返回,varjson将永远丢失

几秒钟后,当Mobile_PortingChain的数据最终到达时:

  • 5、6、7、8(对Mobile_Subrdinate的异步调用)、13、14。作用退货

几秒钟后,当来自Mobile_Subrdinate的数据最终到达时:

  • 9,10,函数返回

这里有一个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
}

再次尝试:一个jsfiddle。