【问题标题】:Javascript global variables only accessible after application runsJavascript 全局变量只能在应用程序运行后访问
【发布时间】:2015-07-28 02:46:07
【问题描述】:

我有一系列对外部 API 的嵌套 Ajax 请求,这非常难看,但这是我可以弄清楚如何使用从前一次调用返回的一些值以指定顺序进行调用的唯一方法。 (我尝试了this,但无法让它工作,所以我回复了here的建议。)

无论如何,这在一定程度上运作良好。我所有的调用都是连续工作的,最后我得到了一个名为people 的数组,它只是一个名称列表:["name1","name2","name3"]

我的问题是我似乎无法从我的 javascript 代码中对这个数组做任何事情。我无法将它们附加到 div,也无法提醒它们,甚至无法在代码执行期间控制台.log 记录它们。但是,一旦我的代码完成,我可以在浏览器控制台中输入people,它们都在那里,正如预期的那样。

我猜这与变量的范围有关 - 我尝试将其设为全局并移动其声明的位置,但我可以从可运行代码访问 people 的唯一方法是从最后的 AJAX 循环,然后我得到很多重复的值,因为它是循环的,并以递增的方式添加到数组中。

这里的目标是从最终的 API 调用中获取人员并在 HTML 中列出他们。

这是我的代码。任何建议都非常感谢。

HTML 触发事件:

<input type='file' accept='image/*' onchange='openFile(event)'>
<!--process is triggered by file upload-->

javascript:

    var openFile = function(event) {

    //... Some UI stuff happens here.
    //... When finished, just call getGraph(); below

    performances = new Array();  // global scope
    people = new Array();  // global scope
    getGraph();  // call function below

    console.log(people);   // retrieve array; doesn't work
  };  

   function getGraph(){ 
    $.ajax({
       url:'http://...' + document.getElementById('prDate').value,
       dataType:'json',
       success: function(response){
           $.each(response, function(i, item) {
               var programID = item.id;
                 $.ajax({
                    url:'http://...'+ programID',
                    dataType:'json',
                    success: function(response){
                        $.each(response, function(i, item) {
                            performances.push( item.id );
                        });
                        $.each(performances, function(index, value){
                            $.ajax({
                               url:'http://...' + this.valueOf() +'/persons/',
                               dataType:'json',
                               success: function(response){
                                   $.each(response, function(i, item) {
                                       people.push( item.firstname + ' ' + item.lastname );  // the magic moment
                                    }); 
                                } 
                            }); 
                        }); 
                    }
                });
            });
        }
    }); 
} 

【问题讨论】:

  • AJAX 调用是异步的,因此只能通过回调访问响应,因此在最终的成功回调中,您可以将人员数组作为参数传递给函数,然后根据它呈现 html。跨度>
  • 从您的代码看来,人们似乎只有在调用 openFile 后才能访问。您是否在openFile 之外尝试过people = new Array();

标签: javascript jquery arrays ajax


【解决方案1】:

从您的代码中可以看出,只有在您调用 openfile 函数时才会创建 people 变量。如果即使没有调用 openfile 方法也希望创建它,然后在所有函数之外声明它,然后它将可以访问,或者在您打算使用它的地方声明它,就像在 ajax 调用上面一样,然后使用它。

【讨论】:

    【解决方案2】:

    您是否尝试将其放入 IIFE 闭包中?

    (function(){
    
      var OpenFile = function() {
    
        if ( !(this instanceof OpenFile) ) {
          return new OpenFile();
        }
    
        var performances = new Array();   // closure Scope
        var people = new Array();         // closure Scope
    
        function getGraph(){ 
          $.ajax({
             url:'http://...' + document.getElementById('prDate').value,
             dataType:'json',
             success: function(response){
                 $.each(response, function(i, item) {
                     var programID = item.id;
                       $.ajax({
                          url:'http://...'+ programID',
                          dataType:'json',
                          success: function(response){
                              $.each(response, function(i, item) {
                                  performances.push( item.id );
                              });
                              $.each(performances, function(index, value){
                                  $.ajax({
                                     url:'http://...' + this.valueOf() +'/persons/',
                                     dataType:'json',
                                     success: function(response){
                                         $.each(response, function(i, item) {
                                             people.push( item.firstname + ' ' + item.lastname );  // the magic moment
                                          }); 
                                      } 
                                  }); 
                              }); 
                          }
                      });
                  });
              }
          }); 
        }
    
        return {
          get performances() : { return performances;},
          get people()       : { return people; },
          getGraph           : getGraph
        };
      };
    
      window.OpenFile = OpenFile;
    
    })();
    

    然后你可以通过做类似的事情来调用它

    var myOpenFile = new OpenFile();
    
    var people = myOpenFile.people;
    
    myOpenFile.getGraph();
    
    console.log(people);
    

    还有一个额外的好处,即 OpenFile 对象在代码加载后立即可用。代码中的所有变量都只作用于对象 OpenFile 并且不会污染全局命名空间,您可以通过将它们放在最后的 return 语句中来选择您希望向其他人公开的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      • 2014-01-17
      • 1970-01-01
      • 2018-10-28
      相关资源
      最近更新 更多